Basic Mapping
mappings use the corresponding return content to be generated according to different URLs requests. Bottle uses the route () decorator to implement the mapping.
From bottle import route, Run@route ('/hello ') def hello (): return "Hello world!" Run () # This starts the HTTP server
Running this program, Access Http://localhost:8080/hello will see "Hello world!" in the browser.
GET, POST, HEAD, ...
This mapping adorner has an optional keyword method that defaults to method= ' GET '. It is also possible to post,put,delete,head or listen to other HTTP request methods.
From bottle import route, Request@route ('/form/submit ', method= ' POST ') def form_submit (): form_data = Request. POST do_something (form_data) return "Done"
Dynamic mapping
You can extract the part of the URL to create a mapping of the dynamic variable name.
@route ('/hello/:name ') def Hello (name): return "Hello%s!"% name
By default, one: Placeholder will always match to the next slash. If you need to change it, you can add regular characters to the #s:
@route ('/get_object/:id#[0-9]+# ') def get (ID): return "Object ID:%d"% int (ID)
Or use a full regular matching group to:
@route ('/get_object/(? P
[0-9]+) ' Def get (ID): return "Object ID:%d"% int (ID)
As you can see, the URL parameter is still a string, even if you are in the inside is a number. You must explicitly type-cast.
@validate () Adorner
The Bottle provides a convenient adorner validate () to validate multiple parameters. It can process each URL parameter by keyword and filter and then return the request.
From bottle import route, validate#/test/validate/1/2.3/4,5,6,7@route ('/test/validate/:i/:f/:csv ') @validate (I=int, F=float, Csv=lambda x:map (int, x.split (', '))) def validate_test (i, F, CSV): return "int:%d, float:%f, list:%s"% (I, F, repr (CSV))
You may need to throw valueerror when the checksum parameter fails.
Return file stream and JSON
The WSGI specification cannot handle file objects or strings. Bottle automatically converts string types to ITER objects. The following example can be run under bottle, but not in a pure WSGI environment.
@route ('/get_string ') def get_string (): return "This is a list of strings, but a single string" @route ('/file ') def G Et_file (): return open (' Some/file.txt ', ' R ')
The dictionary type is also allowed. Converts to JSON format and returns Content-type:application/json automatically.
@route ('/api/status ') def api_status (): return {' status ': ' Online ', ' servertime ': Time.time ()}
You can turn off this feature: Bottle.default_app (). Autojson = False
Cookies
Bottle is to store the cookie in the Request.Cookies variable. The new cookie method is Response.set_cookie (name, value[, **params]). It can accept additional parameters, which are valid parameters for Simplecookie.
From bottle import Responseresponse.set_cookie (' key ', ' value ', path= '/', domain= ' example.com ', secure=true, expires=+ 500, ...)
Set the Max-age property (it is not a valid python parameter name) You can modify the cookie in the instance. Simplecookie Inresponse. COOKIES.
From bottle import Responseresponse. cookies[' key ' = ' value ' response. cookies[' key ' [' max-age '] = 500
Template
Bottle uses a compact template that comes with it. You can use the call template (Template_name, **template_arguments) and return the result.
@route ('/hello/:name ') def Hello (name): return Template (' Hello_template ', username=name)
This loads the HELLO_TEMPLATE.TPL and extracts the url:name to the variable username, returning the request.
Hello_template.tpl roughly like this:
Hello {{username}}
How is it?
Template Search Path
The template is based on bottle. Template_path list variables to search. The default path contains ['./%s.tpl ', './views/%s.tpl '].
Template caching
The template is cached in memory after compilation. Modifying the template does not update the cache until you clear the cache. Call Bottle.TEMPLATES.clear ().
Template syntax
Template syntax is a thin layer around python. The main purpose is to ensure that the correct indentation is in the block. Here are some examples of template syntax:
- %... Python code begins. You do not have to deal with indentation issues. Bottle will do this for you.
- %end Close some statements%if ...,%for ... or something. Closing blocks is a must.
- {{...}} Prints the result of a Python statement.
- %include template_name optional_arguments includes other templates.
- Each row is returned as text.
Example:
%header = ' Test Template '%items = []%include, ' Fly ' Http_header title=header, use_js=[' jquery.js ', ' default.js ']{{Header.title ()}}
%FOR Item in Items:
- %if isinstance (item, int): Zahl: {{item}} %else: %try: Other type: ({{type (item). __name__}}) {{repr ( Item)}} %except: Error:item has no string representation. %end Try-block (yes, you could add comments here) %end
%end
%include http_footer
Key/value Database
Bottle (>0.4.6) provides a key/value database through BOTTLE.DB module variables. You can use a key or a property to access a database object. Call Bottle.db.bucket_name.key_ Name and Bottle.db[bucket_name][key_name].
Just make sure you use the correct name, regardless of whether they already exist.
The stored objects resemble the Dict dictionary, and keys and values must be strings. Items () and values () are not supported. The Keyerror will be thrown if not found.
Persistence of
For requests, all changes are cached in the local memory pool. At the end of the request, the modified portion is automatically saved so that the next request returns the updated value. The data is stored in the Bottle.db_path file. To ensure that the file can access this file.
Race conditions
In general, there is no need to consider locking problems, but in multi-threaded or cross-environment is still a problem. You can call Bottle.db.save () or botle.db.bucket_name.save () to flush the cache, but there is no way to detect the operation of other environments on the database. Until you call Bottle.db.save () or leave the current request.
Example
From bottle import route, Db@route ('/db/counter ') def db_counter (): if ' hits ' Not in Db.counter: db.counter.hits = 0 db[' counter ' [' hits '] + = 1 return "Total Hits:%d!"% db.counter.hits
Using WSGI and middleware
Bottle.default_app () returns a WSGI app. If you like WSGI middleware modules, you just need to declare bottle.run () to wrap the app instead of using the default.
From bottle import Default_app, RunApp = Default_app () Newapp = Yourmiddleware (APP) run (App=newapp)
Default Default_app () work
Bottle creates a bottle.bottle () object and an adorner that calls Bottle.run () to run. Bottle.default_app () is the default. Of course you can create your own bottle.bottle () instance.
From bottle import bottle, Runmybottle = Bottle () @mybottle. Route ('/') def index (): Return ' Default_app ' run (app=mybottle)
Release
Bottle is published by default using Wsgiref.simpleserver. This default single-threaded server is used for early development and testing, but later may become a performance bottleneck.
There are three ways to modify:
- Using multi-threaded adapters
- Load multiple Bottle instance applications
- or both.
Multi-Threaded Server
The simplest approach is to install a multithreaded and WSGI specification HTTP server such as paste, Flup, cherrypy or FAPWS3 and use the appropriate adapter.
From bottle import Pasteserver, Flupserver, Fapwsserver, Cherrypyserverbottle.run (server=pasteserver) # Example
If you lack the server and adapter you like, you can manually modify the HTTP server and set Bottle.default_app () to access your Wsgi app.
def run_custom_paste_server (self, host, port): MyApp = Bottle.default_app () from paste import httpserver Httpserver.serve (MyApp, Host=host, Port=port)
Multi-server process
A Python program can only use one CPU at a time, even if there are more CPUs. The key is to use CPU resources to load balance multiple standalone Python programs.
For single-instance bottle applications, you can start with different ports (localhost:8080, 8081, 8082, ...). The high-performance load acts as a reverse proxy and a new requirement for each random bottle process in the long-term, balancing the behavior of all available support with the load on the server instance. This way, you can use all the CPU cores, even scattered in different physical services