Coder Social home page Coder Social logo

turbogears / tg2 Goto Github PK

View Code? Open in Web Editor NEW
799.0 35.0 77.0 5.78 MB

Python web framework with full-stack layer implemented on top of a microframework core with support for SQL DBMS, MongoDB and Pluggable Applications

Home Page: http://www.turbogears.org/

License: Other

Python 98.52% HTML 1.01% Makefile 0.13% Jinja 0.34%
python python-3 python-2 framework webframework web microframework fullstack

tg2's Introduction

TurboGears

image

image

image

image

image

image

image

image

TurboGears is a hybrid web framework able to act both as a Full Stack framework or as a Microframework. TurboGears helps you get going fast and gets out of your way when you want it!

TurboGears can be used both as a full stack framework or as a microframework in single file mode.

Get Started

image

To try TurboGears just get pip if you don't already have it:

$ curl -O 'https://bootstrap.pypa.io/get-pip.py'
$ python get-pip.py

And install Turbogears:

$ pip install TurboGears2

Then serving a TurboGears web application is as simple as making a webapp.py file with your application:

from wsgiref.simple_server import make_server
from tg import MinimalApplicationConfigurator
from tg import expose, TGController

# RootController of our web app, in charge of serving content for /
class RootController(TGController):
    @expose(content_type="text/plain")
    def index(self):
        return 'Hello World'

# Configure a new minimal application with our root controller.
config = MinimalApplicationConfigurator()
config.update_blueprint({
    'root_controller': RootController()
})

# Serve the newly configured web application.
print("Serving on port 8080...")
httpd = make_server('', 8080, config.make_wsgi_app())
httpd.serve_forever()

Start it with python webapp.py and open your browser at http://localhost:8080/

Want to play further with TurboGears? Try the TurboGears Tutorials:

Support and Documentation

Visit TurboGears Documentation for complete documentation and tutorials.

See the TurboGears website to get a quick overview of the framework and look for support.

License

TurboGears is licensed under an MIT-style license (see LICENSE.txt). Other incorporated projects may be licensed under different licenses. All licenses allow for non-commercial and commercial use.

tg2's People

Contributors

amol- avatar brondsem avatar castixgithub avatar chbrown avatar cito avatar clsdaniel avatar deets avatar ebenmoha avatar elpargo avatar eteamin avatar faide avatar federicofiori avatar lambacck avatar lmacken avatar marcelotduarte avatar markramm avatar mcfletch avatar nphilipp avatar patrickdepinguin avatar pedersen avatar percious avatar ralphbean avatar rick446 avatar schneems avatar sergiobrr avatar smarzola avatar sobolevn avatar turbo87 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

tg2's Issues

How does TurboGears compare with CherryPy?

I am fairly new to web development and I have been working with CherryPy for the last year or so. CherryPy, unfortunately, cannot be installed on BlueHost's shared environment.

I am assuming that TurboGears is a similar product and would love to try it out. Does anyone know if it can be installed on BlueHost or if anyone has installed TurboGears on BlueHost?

DK

bootstrap javascript is broken

I was trying to work out why tooltips didnt work in my turbogears application. The problem is that jquery.js is missing. I have included bootstrap.js in but it doesn't work, including jquery.js (from the twitter github site) make it work immediately.

The relevant code from my mako template is here:

<a href="#" rel='tooltip' class="link" data-original-title="first tooltip">Hover me for a tooltip</a>
<script src="${w.url('/javascript/jquery.js')}"></script>
<script src="${w.url('/javascript/bootstrap.min.js')}"></script>
<script>
$('[rel=tooltip]').tooltip()
</script>

Removing that line mentioning jquery.js makes the tooltip stop working.

Templating support for flash

I really would like to be able to customize the looks of the flash element, and I think using "real" templates would be the best approach (think ToscaWidgets style).

I would try to wrap it around the current implementation using WebFlash so that it needs to be actively activated and configured in app_config but would otherwise be non-disruptive to the current implementation.

Are there any objections if I were to implement it and make a pull request? I.e. would you consider merging it, if it's done properly, or can I spend my time more useful? 😄

Login fails when mod_wsgi WSGIScriptAlias URL-path is not /

I did a simple test -
gearbox quickstart -s -a --disable-migrations myapp
cd myapp
pip install -e .
gearbox setup-app
and I am using mod_wsgi to serve myapp. If the WSGIScriptAlias URL-path is / I can log in using the Login link on the standard web page, or by visiting the 127.0.0.1/admin page. If the URL-path is something like /foo then http://127.0.0.1/foo/ shows the standard quickstart web page. Clicking on the Login link brings me to http://127.0.0.1/foo/login. After logging in as manager I get a 404 error because I am being redirected to http://127.0.0.1/foo/foo/. I'm not sure where the extra /foo is being generated. If I logout and go to http://127.0.0.1/foo/admin I get the login page with http://127.0.0.1/foo/login?came_from=%2Ffoo%2Fadmin%2F as the URL. after logging in as manager I get another 404 page with the url http://127.0.0.1/foo/foo/admin/ Any ideas where the extra /foo is coming from?
Thanks

Admin controller using json gives a JsonEncodeError

Try to go to any admin url with json, such as http://localhost:8080/admin/groups.json and it throws an error.

JsonEncodeError: You may not expose with JSON a list return value because it leaves your application open to CSRF attacks

The controller basically tales a sqlalchemy query and dumps it to the json encoder. I think the error is being thrown within DecoratedController.

Not sure what a list is a problem but a dictionary is ok, but there you go.

cliff.app fails with 'ascii' codec can't encode character

The sqlite DB is empty although I am pretty sure I insert my test data to DB. TurboGears2-2.3.1.

20|17| 45,091 INFO [alembic.migration] Context impl SQLiteImpl.
20|17| 45,092 INFO [alembic.migration] Will assume non-transactional DDL.
20|17| 46,276 ERROR [cliff.app] 'ascii' codec can't encode character u'\u0131' in position 6: ordinal not in range(128)
|| Running setup_app() from acserver.websetup
|| Creating tables
|| Initializing Migrations

@require Should Not Always Redirect To Login

Right now, the require decorator will always redirect to the login page if the user does not have permissions to view the page in question.

Alternate behaviors that should be provided:

  • On detecting a content type that indicates a JavaScript/library type call, return a 403 (XML, JSON)
  • The developer should have the option of always aborting with a 403, and thus end the process, no redirect
  • The developer should have the ability to override the smart handling, and force things to end with a 403.

login redirect strips query params

When going to a url with query params and not authenticated, the came_from param has the query params stripped. Many times links may be provided to uses in emails to specific pages with query params, for example an id of the entity to display. Is there a reason the params are stripped?

I was able to patch this by mofifying line 116 of tg.configuration.auth.fastform.py from

path_info =environ['PATH_INFO']
to

path_info = '%s?%s' % (environ['PATH_INFO'],environ['QUERY_STRING'])

I am not sure if this is the best way to handle it but it is a hold over untill a fix can be added to the code base.

Middlewares' stack order

The default order of the middlewares' stack is (ignoring the TW middleware and the debugger):

Request > RegistryManager > Authentication > Caching > Sessions > Router > TGApp > Response

With this configuration, the thread local context is not available through the RegistryManager, Authentication, Caching, Sessions and Router middlewares, since the above is only generated by the TGApp.setup_app_env() method.

My problem

I'm experiencing this issue while trying to implement caching for my application's authentication process, which is also related to #20.

Having the context generation this deep in the request stack implies that even moving the Caching middleware before the Authentication middleware, I'm not able to use a CacheManager object registered on the Registry, thus eventually leading to possible problems with load peaks.

Wouldn't be better to organize the stack this way?

Request > RegistryManager > Context (new middleware that only generates the request context) > Caching > Authentication > Sessions > Router > TGApp > Response

Row Level Permissions

Hopefully, this link will work:

https://groups.google.com/forum/?hl=en&fromgroups=#!topic/turbogears/J-LHtyjJh_0

A weak spot in TG is the lack of row-level permissions. We have URL based, but row level is non-existent. Having a method which would allow for a user to have ownership and/or permission for a given specific database row would be incredibly helpful.

With the advent of (and expanding use) NoSQL databases like Mongo, this is becoming even more of a requirement.

I'm not sure of the best answer, either. With RDBMS setups, the way to define such permissions is not clearly done. Should we add them as a field at the end of the row? Should we have an associated table for each possible table? Should we have a separate table which handles nothing but permissions? It's awkward.

With Mongo, it's easier: Have a separate set of fields in the document that encapsulates the permissions.

With that in mind, I'm leaning towards having the permissions be a json encoded object at the end of the row, and having something that simply knows how to handle that object. What does everybody else think?

AttributeError: 'function' object has no attribute 'primary_key'

File "D:\Python27\Scripts\tgenv\lib\site-packages\tg\wsgiapp.py", line 105, in call
response = self.wrapped_dispatch(controller, environ, context)
File "D:\Python27\Scripts\tgenv\lib\site-packages\tg\wsgiapp.py", line 278, in dispatch
return controller(environ, context)
File "e:\for_guozhixing\dqwebsvr\dqwebsvr\lib\base.py", line 30, in call
return TGController.call(self, environ, context)
File "D:\Python27\Scripts\tgenv\lib\site-packages\tg\controllers\dispatcher.py", line 132, in call
response = self._perform_call(context)
File "D:\Python27\Scripts\tgenv\lib\site-packages\tg\controllers\dispatcher.py", line 105, in _perform_call
state, params = self._get_dispatchable(context, py_request.quoted_path_info)
File "D:\Python27\Scripts\tgenv\lib\site-packages\tg\controllers\dispatcher.py", line 75, in _get_dispatchable
state = state.controller._dispatch(state, url_path)
File "D:\Python27\Scripts\tgenv\lib\site-packages\crank\objectdispatcher.py", line 188, in _dispatch
state, current_args)
File "D:\Python27\Scripts\tgenv\lib\site-packages\crank\objectdispatcher.py", line 106, in _dispatch_controller
return dispatcher(state, remainder)
File "D:\Python27\Scripts\tgenv\lib\site-packages\crank\objectdispatcher.py", line 191, in _dispatch
return self._dispatch_first_found_default_or_lookup(state, remainder)
File "D:\Python27\Scripts\tgenv\lib\site-packages\crank\objectdispatcher.py", line 132, in _dispatch_first_found_default_or_lookup
new_controller, new_remainder = meth(*m_remainder)
File "D:\Python27\Scripts\tgenv\lib\site-packages\tgext\admin\controller.py", line 133, in _lookup
controller = self.controllers_cache[model_name] = self._make_controller(config, self.session)
File "D:\Python27\Scripts\tgenv\lib\site-packages\tgext\admin\controller.py", line 91, in _make_controller
class ModelController(Controller):
File "D:\Python27\Scripts\tgenv\lib\site-packages\tgext\admin\controller.py", line 95, in ModelController
new_form = config.new_form_type(session)
File "D:\Python27\Scripts\tgenv\lib\site-packages\sprox-0.9.5-py2.7.egg\sprox\configbase.py", line 76, in init
self._do_init_attrs()
File "D:\Python27\Scripts\tgenv\lib\site-packages\tgext\admin\widgets.py", line 94, in _do_init_attrs
super(BootstrapAdminAddRecordForm, self)._do_init_attrs()
File "D:\Python27\Scripts\tgenv\lib\site-packages\sprox-0.9.5-py2.7.egg\sprox\formbase.py", line 471, in _do_init_attrs
pkey = self.provider.get_primary_field(self.entity)
File "D:\Python27\Scripts\tgenv\lib\site-packages\sprox-0.9.5-py2.7.egg\sprox\sa\provider.py", line 170, in get_primary_field
fields = self.get_primary_fields(entity)
File "D:\Python27\Scripts\tgenv\lib\site-packages\sprox-0.9.5-py2.7.egg\sprox\sa\provider.py", line 165, in get_primary_fields
if value.primary_key and not field_name in fields:
AttributeError: 'function' object has no attribute 'primary_key'

class TaskMessage(DeclarativeBase):
tablename = 'task_message'
table_args = {'mysql_charset': 'utf8', 'mysql_engine': 'InnoDB'}
id = Column(BigInteger, Sequence('task_message_id_seq'), primary_key=True)
create_time = Column(DateTime, default=datetime.now)
update_time = Column(TIMESTAMP, default=datetime.now, onupdate=func.current_timestamp())

user_id = Column(Integer, ForeignKey('sys_user.user_id'), nullable=False)
title = Column(Unicode(255), nullable=False)
status = Column(SmallInteger, default=1,doc=u'1:进行中,2:中断,3:完成,4:删除')
is_read = Column(SmallInteger, default=0,doc=u'0:未读完,1:已读完')
task_name = Column(Unicode(63),doc=u'线程名 主要用于取消任务')

class TaskMessageItem(DeclarativeBase):
tablename = 'task_message_item'
table_args = {'mysql_charset': 'utf8', 'mysql_engine': 'InnoDB'}
id = Column(BigInteger, Sequence('task_message_item_id_seq'), primary_key=True)
create_time = Column(DateTime, default=datetime.now)
update_time = Column(TIMESTAMP, default=datetime.now, onupdate=func.current_timestamp())

task_message_id = Column(BigInteger,ForeignKey('task_message.id'),nullable=False)
msg = Column(Text, nullable=False)
is_read = Column(SmallInteger, default=0,doc=u'0:未读,1:已读')

task_messages = relation(TaskMessage, backref='items')

Authorization "bug" in 2.3.5?

Hi everyone, not sure if it's really a bug or a mistake on my side, but here it is:

While upgrading through TurboGears versions (and sometimes merging stuff from fresh quickstarts) I found that my authorization doesn't work properly anymore in 2.3.5.
I'm still using the old authentication layer and in my predicates (https://github.com/moschlar/SAUCE/blob/feature/TG2%2B/sauce/lib/authz.py#L54), I use request.user, which is just request.identity.get('user') and check whether it is equal to or in a relationship attribute on a model object (e.g. request.user in event.teachers). That worked so far, but with 2.3.5, the two objects don't compare equal anymore (both are there and their repr is the same).

Could it be that the two objects are fetched from two separate SQLAlchemy sessions now?

Get tg.decorators Coverage To 90% Or More

When I run python setup.py tgnose and look at our overall coverage, we've allowed things to fall substantially. Right now, I'd like to see tg.decorators go from the current 85% coverage to at least 90% (though 100% would not be unappreciated).

An event stream or event resource with streaming response.

Hello There,
I'm trying to make an event resource for javascript's EventSource object to fire flash messages on client side. But i've found that i'm actually unable to change any tg objects while streaming loop.
The code:

 @expose(content_type='text/event-stream')
 def events(self):

         def stream(): 
             while 1: 
                 yield bytearray(("data: %s::%s\n\n"%(
                     tg.flash.message, 
                     tg.flash.status
                 )).encode('utf-8')) 
                 time.sleep(3)

  return stream()

This code yields messages in format: "data: message::status".

I dont know how tg works under the boonet, but as I understood the changes won't be applied unless the exposed method returns some response.
Currently i fetch flash messages by the means of frontend (i ping some resource after each succefull ajax requst).

I also tried to get gevent-websocket working with tg, but i didn't see required changes in wsgi environ (wsgi.websocket object)
I see it's not so simple, but I hope you can give me rigiht dirrection to find an approach to this issue.

Permit to skip message escaping in flash messages

From mailing list it has been reported the need to place links into the flash messages, while this is not always desiderable it might make sense in some cases.

Suggested implementation on ML was:

def _render_static_version(self, container_id):
        payload = self.pop_payload()
        if not payload:
            return ''

        # HACK - THIS IS A PATCH
        if payload.get('no_escape'):
            payload['message'] = payload.get('message','')
        else:
            payload['message'] = escape(payload.get('message',''))

        payload['container_id'] = container_id
        return self.static_template.substitute(payload)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.