
I only know PHP. How do I write a Web application in Python? - jrheard
http://me.veekun.com/blog/2012/05/05/python-faq-webdev/
======
Xuzz
I'd say the necessity of this post is _why_ PHP is as popular as it is. With
PHP, there are no package managers I have to install; there is no template
language to learn; there is often no version control; there is no "framework";
etc. You just drop in a .php file and, most likely, it will just run. If I
need a quick dynamic page on my server, it's much easier to do this in PHP
than in Python or Ruby.

Until Python or Ruby have that kind of simplicity, they can't overtake PHP.
While it might not be the kind of design that leads to well-designed web apps
or even good code, it is the kind of design that leads to more — especially
less technical, or, like me, lazy — users. It's up to the developers of those
languages if this is even a market they want. There may need to be something
new to do the same job as PHP, but better, without the innumerable warts.

~~~
zokier
CGI scripts have much of PHPs simplicity. You can just drop in a executable
file, and depending bit on server configuration, it will just run. With Python
a basic hello world would look something like this:

    
    
        #!/usr/bin/python
        
        print "Content-type: text/plain"
        print ""
        print "Hello World!"
    

So 3 lines of "boilerplate", and then you can do anything you want. No extra
packages to install or languages to learn. No frameworks necessary.

edit: just as an example of minimal hello world in WSGI:

    
    
        def application(environ, start_response):
            start_response('200 OK', [('Content-type', 'text/plain')])
            yield 'Hello World!'
    

also doesn't need any extra python packages or frameworks. but configuring web
server to handle wsgi is bit more involved than cgi.

~~~
mjschultz
Let's look at the PHP version:

    
    
        Hello World!
    

One line. I didn't have to worry about Linux/Windows, knowing HTTP headers or
the fact that I need two CRLFs after the last header[1]. I just wanted a page
that says "Hello World!" and that's what I got.

Don't get me wrong, I would never choose to write a web app in PHP over
python. But it is brain dead simple to go from nothing to something in a few
keystrokes. Which is precisely what people just learning to write web apps
want (right or wrong).

[1] I can't remember how long it took me to figure out that I needed the
second CRLF after the "Content-Type: text/html" when I was learning perl (or
even the fact that I needed to specify the Content-Type in the first place).

~~~
zokier
In the context of the parent comment I'd argue that the differences are
insignificant. Xuzz argued that PHP is simpler because you don't need to know
the ecosystem. Which I countered by showing a basic example of Python which
doesn't depend on the ecosystem (like frameworks, package managers or version
control).

Besides that, I don't think knowing HTTP headers or understanding significance
of trailing newlines is required to write CGI scripts. You only need to know
that you need those three 'magic' lines in the front of your scripts.
Similarly like you need to know that in php you need <?php ... ?> around your
script.

~~~
mjschultz
But I never needed to worry about those three lines in PHP, to a new user that
is important. To you and I they come naturally.

PHP "is especially suited for Web development and can be embedded into HTML"
[1]. Python "lets you work more quickly and integrate your systems more
effectively" [2]. They can both do the task of the other, but the upstart time
for a developer to handle the task of making a web app is smaller for PHP.

I've never taken the non-framework approach with python for anything
significant, but how does it handle cookies, GET and POST fields, sessions,
and file uploads? In PHP you'd have $_COOKIE, $_GET, $_POST, $_SESSION, and
$_FILES as built-in global variables.

Are these differences still insignificant?

[1] <http://php.net/> [2] <http://python.org/>

~~~
eevee
Python has a `cgi` module that does most of the superglobal stuff for you.

But, er. Does this really matter? Yes, you can get "hello world" in PHP with
one line of not-PHP. You can also get "hello world" in Python + Flask with
seven lines, _and_ you'll get half a dozen extremely nice features for free
that you can learn about as you go.

Arguing about what stack has the simplest way to build from total scratch is a
sad race to the bottom. I'd rather be making the point that _rich_ Web
development can be easy, not that cobble-your-own-thing-together-with-duct-
tape can be easy.

~~~
mjschultz
The first poster in this thread made the statement: "If I need a quick dynamic
page on my server, it's much easier to do this in PHP than in Python or Ruby."

So yes, it really does matter in the context of this thread. On the whole I
agree with your philosophy that frameworks are there for a reason: you get
many features for almost nothing.

But sometimes you just don't need a framework, you need something quick-and-
dirty that just works.

~~~
eevee
But even something quick and dirty is longer than "hello world". I've written
a couple pretty dinky things with Flask, and the minuscule overhead of typing
`import Flask` was definitely worth having e.g. a solid template language and
XSS protection ready to go.

------
yaix
Nice littel overview, but...

"Unicode sucks. This is a universal truth."

And here I stopped reading. Unicode is the best thing around, what sucks it
that Py2 does not implement it very well. Py3 does, and that is the main
reason I really would like to use it and hope Django will soon fully support
it. (Because: there are other languages beside the European ones)

~~~
eevee
Fair point. Correction: working with encodings sucks.

Py3 isn't _magnitudes_ better with Unicode; it's better about converting
incoming bytes, and it makes literals into real strings. But the former isn't
necessarily a good thing, and you can get the latter with a `__future__`
import. Always dying on implicit conversions is definitely nice, though.

~~~
jeltz
Working with encoding is not that bad in for example Ruby 1.9. What makes them
horrible to work with are the bad design decisions in Python, especially
Python 2.

~~~
eevee
I've only read about Ruby strings, not used them, but they seem like a middle
ground between Perl's approach and Python's approach. What do you perceive as
the problem with Python?

------
bobsy
I would love to switch to Python from PHP but I can't. The reason is I keep
getting told to learn Python 2. Python 3 has been out for ages!

Basically I am concerned that I will learn something and create app's which
within a year will be out of date. I am confused why Python developers are
advocating that newbies learn an old and presumably soon to be legacy version
of the language.

I remember when this kinda happened with PHP and versions 4 and 5. I still run
across hosts who default to PHP4!? WTF? Its 2012!

Is PYthon3 really that new that you shouldn't pick it up or is this developers
still refusing to update?

~~~
eevee
Python 2 versus 3 isn't anything like PHP 4 versus 5.

The problem is that there are a few minor but backwards-incompatible changes
to the _syntax_ in py3. Libraries can't update until all their dependencies
update. And web frameworks are some of the most complex software with the most
dependencies, so they're updating last.

It's still pretty much the same language behaving in the same way, though. If
you know Python 2 really well, it'll take all of five minutes to get
accustomed to Python 3. Just don't worry about it and learn 2 until people
stop telling you otherwise. :)

~~~
mkopinsky
"Don't worry, migration from Python 2 to 3 is really easy. It'll take 5
minutes to learn."

"Migration for libraries from Python 2 to 3 is really hard. It's taken them a
few years and counting."

??

~~~
eevee
Right. _Learning_ Python 3, once you know 2, is really easy.

Library maintainers have two problems: they have to twiddle their thumbs until
all their dependencies have ported, and then they have to get their code
running against both 2 and 3. The former is exactly why I'm saying to use 2
for now, and the latter is easy if you only support 2.7 but rather more
difficult for projects that still want to run on some archaic thing like 2.3.

------
VBprogrammer

       The idea is that a transaction starts when a request  starts, and it’s automatically rolled back if there’s an exception. This is behavior you want from the start! It’s half (err, ¼) the point of using a database.
    

I mostly agreed with the rest of the article but this strikes me as massive
blooper. I can see no reason this would be considered good advise.

It's the database equivalent of the GIL, can't figure out what you actually
need to lock? Just lock everything!

An example of this going wrong in production, I work in the online gaming
(gambling) industry. One of our users won a large jackpot, our code started a
transaction, contacted the 3rd party to have them release the funds, recorded
the win in the transaction journal, updated the customers balance etc. Then
the stored procedure which inserted a row into the outgoing email queue had a
small error. This caused all of the database work on our end to rollback.

For what its worth, this was discovered during a reconciliation with the 3rd
party and the customer received his winnings.

My point being, this is a horrible way of dealing with database transactions.
Only things which are transactional by nature should be carried out within the
same transaction. Obviously your code needs to deal with any errors and carry
on or report an error as is appropriate.

~~~
zzzeek
> An example of this going wrong in production, I work in the online gaming
> (gambling) industry. One of our users won a large jackpot, our code started
> a transaction, contacted the 3rd party to have them release the funds,
> recorded the win in the transaction journal, updated the customers balance
> etc. Then the stored procedure which inserted a row into the outgoing email
> queue had a small error. This caused all of the database work on our end to
> rollback.

Updating a customer's winnings and recording a win are _definitely_ things
that should be together in a transaction - if one happened and not the other,
that's a failure.

This is not the fault of using a transaction, this is the fault of not working
with what is essentially a _distributed_ transaction. Since you are relying on
a message against a third party, you need to build distribution into this
system, which is challenging. You might contact the third party _after_ you've
completed the internal processing, and you might use two-phase semantics even
such that you can "PREPARE TRANSACTION" the work you've done locally, (nearly)
guaranteeing that a commit will proceed, then work with your external
messaging, then commit locally.

background at <http://en.wikipedia.org/wiki/Two-phase_commit_protocol>

~~~
VBprogrammer
> Updating a customer's winnings and recording a win are definitely things
> that should be together in a transaction - if one happened and not the
> other, that's a failure.

Yes, they these clearly do belong in the same transaction. Inserting a
congratulations email into the email queue doesn't.

~~~
zzzeek
emails typically get fired off as part of a post-commit hook. Pyramid's
transaction manager has explicit support for this pattern - as you establish
"emails" within your trans, the actual send operation is deferred til after
the transaction proceeds.

------
gbog
"MySQL is the PHP of databases". Strange, I just had this sentence popping in
my head yesterday. I'm seriously considering writing a list of its wrong
doings.

Great article overall.

~~~
glogla
Color me as another interested specimen.

~~~
gbog
I wanted to do that now but did some lego with my kid instead, will keep you 3
informed when done.

~~~
gbog
It seems an article on Ars Technica has already compiled some defect of MySQL:

[http://arstechnica.com/civis/viewtopic.php?f=20&t=92525](http://arstechnica.com/civis/viewtopic.php?f=20&t=92525)

Another thing that reminds of PHP, the list of commands:

    
    
        mysql                       mysql_client_test_embedded  mysql_find_rows             mysqlrepair                 mysql_tzinfo_to_sql
        mysqlaccess                 mysql_config                mysql_fix_extensions        mysqlreport                 mysql_upgrade
        mysqladmin                  mysql_convert_table_format  mysql_fix_privilege_tables  mysql_secure_installation   mysql_waitpid
        mysqlanalyze                mysqld                      mysqlhotcopy                mysql_setpermission         mysql_zap
        mysqlbinlog                 mysqld_multi                mysqlimport                 mysqlshow                   
        mysqlbug                    mysqld_safe                 mysql_install_db            mysqlslap                   
        mysqlcheck                  mysqldump                   mysqlmanager                mysqltest                   
        mysql_client_test           mysqldumpslow               mysqloptimize               mysqltest_embedded  
    

Why the hell show we want a 'mysqldumpslow'? Is it because mysqldump is fast
but wrong? And why not mysql_dump?

I have started with MySQL for my first (php) website, and to me the database
was just the natural storage, I had no idea of the problems, because I didn't
know that a relational database is a particular well-defined mathematical
object, which asserts truths about the "world" in a manner that makes it
possible to model this world safely and ask questions about it. Then I used
PostgreSQL at my previous work, and discovered it all, the hard way. And
PostgreSQL has (almost) always been a reliable companion taking care of the
most valuable asset: the Data. Then I switched job and have to use MySQL
again. I live with it, it's fine, but the difference is not benign, and I
sometime wonder if the NoSQL movement is not a partly a misunderstanding and
should renamed NoMySQL: when using an unreliable datastore, it is certainly
better to use one that is explicitly not reliable and do not force on you the
relational model while, at the same time, not giving you its strengths.

~~~
pjscott
In case anybody was wondering: mysqldumpslow is for dumping MySQL's slow query
log.

------
jiggy2011
Is there any cheap & easy webhosting available for Python?

Occasionally I get commisioned to build small websites ( < 50 visitors per
day) and for that I want to be able to build the site in a day or two.

I don't want the hassle/expense of having to setup and run VPS/AWS
infastructure. I just want to give someone a bunch of files and say "sign up
for some cheap webhosting, ask them to give you a DB called X and upload
these".

I usually end up just doing it in PHP, but it has always felt like a poor
reason to choose a language with so many warts.

~~~
tantalor
Heroku is a good choice,

> This quickstart will get you going with Python and the Flask web framework
> on the Cedar stack. For Django apps, please see the Django quickstart.

<https://devcenter.heroku.com/articles/python>

It can be very cheap or free at low scale,

> Each application receives 750 free dyno hours per month.

<https://devcenter.heroku.com/articles/dynos>

~~~
evilduck
Replying to Jiggy, but can't directly reply since it's dead:

No, a simple Rails app is not very coupled to Heroku.

The deployment process is simpler and pretty unique to Heroku, but it's
usually pretty easy to move away from Heroku or deploy in parallel to another
location. I actually deploy one app to Heroku and I have an offsite backup
process that deploys the same codebase to a NGINX/Passenger setup and clones
the production Heroku data to that instance.

Your mileage will vary, of course. If you start using a bunch of Heroku
plugins, you'll find it's harder to maintain an easy dual-deploy setup.

------
achristoffersen
I have no idea why web2py gotten such a bad rep. I am a beginning webdeveloper
and seriously: web2py is a pleasure to work with. Simple to start, deploy,
port and hack. It's backwards compatible and has a template language that
really is non existant as so far as its pure python.

Compare that to Rails - which is (comparable) hell to set-up and breaks with
upgrades etc.

If you want python web development to be simple, web2py is the way to go.
Since I don't have a CS degree and I have often been wrong before - there
might be a real problem somewhere. But I don't think so. One of the reasons
for this is that Jakob Moss removed his web2py bashing from this thread.
Didn't edit - removed it: [https://www.quora.com/Is-web2py-a-good-Python-web-
framework/...](https://www.quora.com/Is-web2py-a-good-Python-web-
framework/answer/Anthony-Bastardi)

~~~
irahul
> But I don't think so. One of the reasons for this is that Jakob Moss removed
> his web2py bashing from this thread. Didn't edit - removed it:
> [https://www.quora.com/Is-web2py-a-good-Python-web-
> framework/...](https://www.quora.com/Is-web2py-a-good-Python-web-
> framework/..).

What did he remove?

[https://www.quora.com/Is-web2py-a-good-Python-web-
framework/...](https://www.quora.com/Is-web2py-a-good-Python-web-
framework/answer/Jacob-Kaplan-Moss-1)

This isn't the first instance of Django/Flask people not agreeing with web2py
design and implementation, and they have been vocal about it a couple of
times.

[http://www.reddit.com/r/Python/comments/ex54j/seeking_clarif...](http://www.reddit.com/r/Python/comments/ex54j/seeking_clarification_on_pylonsturbogearspyramid/)

Look for comments by mitsuhiko(flask dev) and jacobian(django dev).

~~~
achristoffersen
Sorry - I remembered that I on an earlier occasion couldn't find JKM' answer.
It's there now - and I personally don't find it convincing. Again - I am a
novice and has no authority here. – I'd edit above if I could. I am sorry that
I wrote wrong info.

Thanks for the reddit link. As you say it seems to me most of the flak is from
not agreeing on something. But can an oppinion be correct?

And yes: Mitsuhiko seems to be a super cool, clever and friendly guy. In my
last project I played around with request. Lovely it was.

Anyways: my point was not to express that web2py is the greatest thing
invented since bacon. Only that I don't understand why the python community
dislike it so. After all - web2py makes it very easy to build stuff. Hence it
will probably attract people to the language. Hence make it more feasible for
webhosts to offer python friendly environments. And that should be a good
thing? Especially in the context of OP - "how do PHP guy start with python"?

~~~
brass9
>And yes: Mitsuhiko seems to be a super cool, clever and friendly guy. In my
last project I played around with request. Lovely it was.

That would be kenneth reitz <https://github.com/kennethreitz>

But I do agree, mitsuhiko is a super-cool guy!

------
optymizer
Personally, I _like_ PHP because, at the core, it is a collection of utility
functions to write webapps quickly. Here's a small set of those function that
I would like to see somewhere else (like in Python for example):

Save a file: file_put_contents()

Load a file: file_get_contents()

Trim whitespace: trim()

Print a string (even numbers!): print $str

Dump an array: print_r()

Print the stack trace: print $e->getTraceAsString()

Want to embed HTML? Go ahead, _without_ any of this nonsense: print
"<table><tbody><tr><td>"+str(val)+"</td></tr></tbody></table>"

Want to check for errors and improve the quality of the code? Go ahead! Use
lower level functions like fwrite, fread, etc; most functions return FALSE on
error, use try/catch, throw Exceptions, create custom Exception classes, go
nuts with over-architecting if that's your thing.

Also, as someone who knows C and C++ rather well, I find PHP completely
intuitive, very easy and flexible, as opposed to:

    
    
      if __main__=="__main__": 
          main()
    

and passing self around is just plain redundant.

The icing on the cake is that a huge part of the built-in functions wrap and
extend existing C functions: strpos, strlen, so the language rarely gets in
your way. The docs are pretty good (there's room for improvement).

So you can be a zealot all you want, but the truth is: the language doesn't
make your code reliable - YOU make the code reliable and, from my experience,
people who bash a language rarely know what they're talking about and it
usually just boils down to personal preferences like braces vs no-braces.

Lastly, I wish you all the best in your fanatic bashing of a good tool that
has proven itself appropriate for web applications. Everyone's tired of the
following example, but I'm going to say it anyway: Facebook (and thousands of
other large websites). Feel free to be in denial about that.

~~~
egonschiele
In Ruby:

    
    
        # Save a file
        f.write(str)
    
        # Read a file
        f.read
    
        # Trim whitespace
        " foo ".strip
    
        # Print anything
        puts 1 # even numbers!
        puts File.open("foo", "w+") # even file handles!
        puts [1, 2, 3, 4] # even arrays!
        puts [].class # even classes!
        puts [].method(:size) # even functions!
    
        # Dump an array (see above)
    

Python is similarly clear:

    
    
        # Save a file
        f.write(str)
    
        # Read a file
        f.read()
    
        # Trim whitespace
        " foo ".strip()
    
        # Print anything
        print 1 # even numbers!
        print open("foo", "w+") # even file handles!
        print [1, 2, 3, 4] # even arrays!
        print [].__class__ # even classes!
        puts [].remove # even functions!
    
        # Dump an array (see above)
    

Ruby and Python are _extremely_ well documented. They have great standard
libraries which wrap existing C functions too...and wrap them in a
_consistent_ fashion. They are also the second and third most popular language
on Github, respectively...which means tons of great libraries to solve almost
any problem you can think of.

Ruby and Python are just as easy to use as PHP.

~~~
getsat
Not sure about the Python ones, but the Ruby read/write file examples aren't
quite fully done/correct here:

    
    
      # Equivalent of file_put_contents() in PHP
      # This could also be used for appending if the correct mode is specified.
      File.open("filename", "w") { |f| f.write("some data") }
    
      # Equivalent of file_get_contents() in PHP
      some_var = File.read("filename")

~~~
jeltz
Ruby 1.9.3 added File.write("filename", "some data").

~~~
getsat
Cool. Didn't know that. Thanks.

------
ashray
This guy failed to cover web.py which is one of the fastest ways to start
prototyping a web app in python. =/

<http://webpy.org/>

I personally use it for a small app which returns (and stores) search
suggestions from redis.

------
wink
I was thinking this could redeem the author's credibility a little after the
PHP rant, but the irrational hatred for Cheetah sounded very familiar.

I only used it in one project, a few years ago, but there's really no bad
thing about it I couldn't say about any other templating system in any
language I ever tried.

I wouldn't really take offense with that, but while the XSS chapter still has
some points, the Sanitizing chapter goes on to bash PHP for a subjective trend
of sanitizing (examples?) just to go on and present an example of sanitizing.

In general, it was a decent article, but sadly again much more opinionated
than needed. It's one thing to suggest one technology over the other but it
doesn't help to make people who actually agree with your point have their eyes
rolling every second paragraph. (That the author doesn't like MySQL was to be
expected after the PHP rant as it usually goes hand in hand, but showing some
real reasons for Postgres over MySQL would have been nice.)

Still the same criticisms apply, I'd wager most people use PHP (or MySQL for
the matter) because it's MINDBLOWINGLY AMAZING, but because a) the
infrastructure is set up (especially DBAs hate to mix and match in my
experience) b) the people at hand can use the language and use it well c) it
gets the job done. quickly. sometimes "good enough".

~~~
jeltz
Explaining why what he does not like about MySQL would have been moving too
far from the subject of the article.

And I liked the sanitizing chapter. It explains well why "sanitizing" is a
misused word, which should be avoided. Almost always when I see people call it
"sanitizing input" they do not seem to know how to handle input correctly.

~~~
eevee
I don\'t see the problem with \"sanitizing\". It\'s easy: just add a \\\
before every quote and the string is totally safe!

------
capkutay
I like java for web app development, simply because it has a well-structured
api and a massive community of developers who have run in to the majority of
the road blocks you will most likely encounter on the way to launching your
app.

~~~
yolesaber
What frameworks and platforms would you recommend for web development with
java? I am writing my senior project at college in java (mainly because of the
wide amount of image processing libraries available) and would love to add web
capabilities.

~~~
cletus
I tend to prefer Python/Flask for Web dev to Python but if you are inclined to
use Java there's only really one framework that doesn't make me want to tear
my eyeballs out.

That framework is Spring MVC.

It is DI, adapters for vendor-specific libraries and utility. It's probably
not the easiest thing to start with just because it is so flexible that it can
be hard to know where to start. A good "Hello World" Spring MVC 3.1 app would
go a long way.

I really would like to use the Play Framework and it's so close to being great
but it just falls too far short.

I really liked Play 1.x with Groovy templates. It was simple and it pretty
much just worked.

Play 2.x has gone in a radically different (and backwards incompatible)
direction. It is now part of Typesafe and the goal of Play 2.x is to make
Scala a first-class citizen.

The problem is that many of the niceties of Play are either harder to use or
just outright missing in Java Play 2.x (eg AppEngine support and the OAuth
client were all present in 1.x and are slated for a future 2.1 release).

There really is a niche for a Java Web framework that like Play ditches the
JEE/servlet model in favour of the Rails/Django way of doing things (including
dynamic class reloading) but doesn't do it in a way that makes me want to stab
myself repeatedly.

This would include playing nice with the Java ecosystem (seriously just use
Maven and to hell with SBT).

~~~
mgkimsal
Grails (grails.org) is Spring under the hood, good MVC layer on top, and gives
you Java or Groovy wherever you want to use it. For people coming from a
dynamic language background (php, python, ruby, etc) I've found that Grails is
a good middle ground option.

------
languagehacker
I really don't think it's worth taking this guy seriously. First he writes a
worthless and inaccurate lambast of PHP, and now he's trying to "convert"
people to Python by telling us Unicode sucks. Get a life.

~~~
damncabbage
> _... by telling us Unicode sucks._

Could you tell us where he did this?

(I didn't notice it on the first time through; he did say to use Unicode
everywhere inside your code, though, and to not do anything rude like
converting Unicode to ASCII by stripping non-latin1 characters.)

~~~
smacktoward
Right under the big bold "Unicode" header. The very next line is

 _> Unicode sucks. This is a universal truth._

(In fairness, I think what he's really getting at is that _dealing with
Unicode in languages that were created before it became ubiquitous_ sucks, not
Unicode itself. But if you start off your discussion of Unicode with the
statement that "Unicode sucks", you shouldn't be surprised if people think
your beef is with Unicode rather than with the tools we use to deal with it.)

~~~
damncabbage
Point. Mind you, he follows that with:

 _"(I’m lying. Dealing with encodings sucks. Unicode is great. It’s
complicated. I’ll write about it later.)"_

I think I'll wait for the follow-up article.

------
gouranga
Good article apart from one thing - avoid the hell out of session state. This
becomes the dumping ground for all sorts of crap and will slowly knacker your
app. You should only persist enough information to identify the user between
requests and keep the rest stateless. We do that using encrypted cookies
containing the user id, display name and correlation id.

I've just spent 6 months entirely removing session state from an asp.net app
and the performance gain is amazing.

------
salimmadjd
Great article! For those of you who say how easy PHP is, it's because you
don't remember the early days when you had to compile php to run on your box,
only to watch it fail after an hour of compilation :) history aside, these are
just tools. For many site, perhaps for majority of tasks, PHP might be the
best tool for the job. Once you start doing more complex stuff that will
require additional libraries and modules then you need to look into other
languages.

I used servlets from very early days, just because I could never understand
another man's perl code and I thought the architecture was better. However
J2EE got so big and academic that took all the fun out of coding. I've
recently started to do some stuff in python and the fun is back again. I love
all the NLP libs that are available for python in addition to vast support and
ease of coding. Not to mention, I like the python community more than ruby
(rails really). It just seems like python guys come from a stronger CS
background and are not some over-night rail guys who want to push their faith
down your throat.

------
pbreit
By far the easiest way to get started with Python web development is Web2py
which comes as a self-contained install where you can get started in 5
minutes. So you automatically get "request" information, big deal.

~~~
eevee
Flask comes as a self-contained install where you can get started in 5
minutes.

~~~
pbreit
Flask doesn't help much with the database.

------
Marwy
I've seen Flask mentioned here few times. Is Flask better than Bottle?

~~~
lclarkmichalek
In my humble opinion.. Yes. I feel bottle sacrifices just a little too much
for the sake of being a single file distribution. The lack of any (mainstream)
templating engine might hinder newcomers, and Flask uses one of the best
python templating engines around. I also find Flask's documentation to be more
extensive and better laid out. Overall I would recommend Flask if you want to
write a full featured website, Bottle if you are looking to write some kind of
API layer, or similarly bear bones functionality, and will not require many
"batteries included".

~~~
Marwy
You can use Jinja2 with Bottle:

> pip install Jinja2

from bottle import jinja2_template as template

------
exim
In python, stay away from default arguments for methods/functions.

EDIT: yes, mutable default values:

<http://effbot.org/zone/default-values.htm>

~~~
espeed
Do you mean don't use defaults that contain mutable values?

------
akkartik
What's wrong with mysql?

~~~
cbg0
Apparently, it isn't PostgreSQL; If you have no need for Postgres features and
you're not familiar with it, sticking to MySQL is fine.

~~~
gbog
Well you can say the same for windows vs Linux or visual basic vs any other
language, and you can also continue using paper glue to attach paintings on
the wall.

It is not a matter of what you need, it is a matter of using good tools that
will help you do good work, understand better what you do, build durable
products, and so on.

Just one example: MySQL will not complain if you add a check constraint but
will not actually add it to your schema. That's a very Microsoft-y way to
handle things, and should give cold sweat to any coder.

~~~
cbg0
This is actually documented behavior: "The CHECK clause is parsed but ignored
by all storage engines." From: <http://dev.mysql.com/doc/refman/5.5/en/create-
table.html>

I believe it was left to support certain migrations(?). You can create a
trigger instead.

I'm pretty certain many people will consider MySQL a good tool with which they
produce good work. While it may have its quirks, it's present on virtually all
shared hosting environments, just like PHP, so it's very easy to create and
deploy an application powered by both these technologies.

~~~
gbog
So, you are telling me that it is a good thing, a normal behavior for a
reliable tool to just ignore instructions I send to it and do nothing with it,
not even a warning? So when I migrate a database, I have to carefully check
each and every instructions (schema and data) and make sure MySQL did not
"decide" it was not worth it and just silently threw it by the window?

I have hard time to believe you are serious here...

~~~
cbg0
I'm pretty certain when you migrate from a different database you're supposed
to check your schema and data anyway, or do you just "decide" it should work
without question?

I'm not saying this MySQL behavior is acceptable, I'm just saying that you
should be aware of the limitations and quirks of the tools you work with.

~~~
emil0r
So it's not acceptable behaviour, yet we shouldn't point it because we should
know it has this unacceptable behaviour? Doesn't make any sense to me I'm
afraid.

------
prezjordan
off-topic: love the greek-lettered ordered list.

------
pimentel
Should I really learn Pyramid instead of Django? I'm thinking about what would
give me most value as a developer, one who already knows his python.

~~~
grey413
It's a tradeoff. Django is a full-stack framework, which integrates lots of
components such as templates, form generation, and an ORM. This means that you
can get off the ground quicker, and that the community is all more or less on
the same page. The downside is that if you want to do something that Django
isn't good at (complicated database stuff, logic in templates, etc), you are
in for a world of pain (reportedly). Overall, Django is a great default for
making CMS-type sites, but can become a technical debt if your requirements
outgrow it.

Pyramid, on the other hand, deliberately not a full stack framework,
sacrificing ease-of-use for flexibility. It doesn't include any database
opinions at all, can swap templating languages on a whim and wouldn't know a
form if you hit it over the head with one. The upside is that it has first
class core components, really well defined extension points, an unmatched
routing system, and a few truly excellent plugins (I love you pyramid_tm). The
downside, of course, is that you will own your entire stack, which means that
A) there is more up-front work researching, designing, and developing your
application's component stack and B) there's no central community guaranteed
to be using the same stack as you. Overall, pyramid is suited for essentially
any use case, so long as you put the work into it.

tldr: Django is (somewhat) inflexible but easy, Pyramid is flexible but more
demanding. Both are excellent.

There are probably more jobs working with Django, if that's a consideration.

------
javajosh
Google App Engine for Python. You don't have to configure your host, you get
great tooling and documentation, and a very good community of users.

------
jipipayo
Its funny how Ruby hordes overwhelms this thread talking about ruby not python
nor php :-D

------
tantalor
> Some have helpers for creating RESTful routes

Can somebody point to an example of this?

------
jpwagner
Great overview.

------
gcb
Say wat you want of php. But it's (insert personal pejorative option) made for
it.

Sure Its a_little_inconsistent AndSomewhatChaotic

But all the basics for the web are incredible accessible right away.

With every other language you have to start with a framework.

I find php easier than rails to prototype applications and do fast hacks that
need a web face.

It's simply the right tool for the job on those occasions. Of course, later
they become huge systems...

~~~
BrandonM
That's a nice sentiment that's completely inaccurate. Even 6 years ago when I
first started programming Python, simple Python cgi scripts were very easy to
write. It's as simple as:

    
    
      print """\
      Content-type: text/html
      
      <html>...</html>"""
    

With %(var)s interpolation, you can even slap in locals() easily to trivially
put variables' values into the page.

~~~
eli
That doesn't seem like it will scale very well at all. Or am I missing
something?

~~~
justincormack
PHP doesn't scale well either. You can rewrite for scaling later.

------
zobzu
"I only know PHP"

"I just trashed PHP rather harshly"

"I want to learn python"

Well, you're doing it wrong. How can you trash PHP if you know _no_ _other_
_languages_ ?!

You're following articles, posts saying PHP is bad and.. you decide then
that's right it's bad!

Ever though about _thinking_ on your own first? Like, actually trying a
language (python, why not) _then_ deciding if it's better?

This kind of stuff always amaze me. You know, sheepish.

~~~
eevee
This is part of an FAQ series. The bolded part ("I only know PHP...") is the
question I'm answering.

I'll leave you to contemplate the irony here.

