This module is the foundation of Smisk and is implemented in machine native code.
See C API for documentation of the C interface.
| Requires: | libfcgi |
|---|
Build identifier in URN form, distinguishing each unique build.
| See: | smisk.release.build for more information about this attribute. |
|---|
Changed in version 1.1.0: Prior to version 1.1.0, this was a abritrary (per-build unique) string. In 1.1.0 this is now a URN.
Current Application (None if no application has been created).
This is actually a smisk.util.objectproxy.ObjectProxy, inducing a slight performance hit, since accessing the actual application causes intermediate calls. Application.current is the most performance-effective way to access the current application. However, in most cases the performance hit induced by the ObjectProxy is so small, the increased readability and usage of app is preferred.
Example:
>>> import smisk
>>> smisk.app
None
>>> import smisk.core
>>> smisk.core.Application()
<smisk.core.Application object at 0x6a5c0>
>>> smisk.app
<smisk.core.Application object at 0x6a5c0>
| See: | Application.current |
|---|
New in version 1.1.0.
Current Request (None if no application is running).
This is actually a smisk.util.objectproxy.ObjectProxy, inducing a slight performance hit, since accessing the actual application causes intermediate calls. Application.current.request is the most performance-effective way to access the current request. However, in most cases the performance hit induced by the ObjectProxy is so small, the increased readability of request is preferred.
| See: | Application.request |
|---|
New in version 1.1.0.
Current Response (None if no application is running).
This is actually a smisk.util.objectproxy.ObjectProxy, inducing a slight performance hit, since accessing the actual application causes intermediate calls. Application.current.response is the most performance-effective way to access the current response. However, in most cases the performance hit induced by the ObjectProxy is so small, the increased readability of response is preferred.
| See: | Application.response |
|---|
New in version 1.1.0.
Bind to a specific unix socket or host (and/or port).
| Parameters: |
|
|---|---|
| Raises: | smisk.IOError If already bound. |
| Raises: | IOError If socket creation fails. |
| See: |
Unbind from a previous call to bind().
If not bound, calling this function has no effect. You can test wherethere or not the current process is bound by calling listening().
| Raises: | IOError on failure. |
|---|
New in version 1.1.0.
Find out if this process is a “remote” process, bound to a socket by means of calling bind(). If it is listening, this function returns the address and port or the UNIX socket path.
See also: unbind()
| Raises: | smisk.IOError On failure. |
|---|---|
| Returns: | Bound path/address or None if not bound. |
Generate a universally Unique Identifier.
See documentation of pack() for an overview of :func:nbits.
The UID is calculated like this:
sha1 ( time.secs, time.usecs, pid, random[, node] )
| Note: | This is not a UUID (ISO/IEC 11578:1996) implementation. However it uses an algorithm very similar to UUID v5 (RFC 4122). Most notably, the format of the output is more compact than that of UUID v5. |
|---|---|
| Parameters: |
|
New in version 1.1.0.
Pack arbitrary bytes into a printable ASCII string.
Overview of nbits:
| Parameters: |
|
|---|---|
| See: |
New in version 1.1.0.
Calculate a hash from any python object.
New in version 1.1.0.
An application.
Simple example:
from smisk.core import Application
class MyApp(Application):
def service(self):
self.response.write('<h1>Hello World!</h1>')
MyApp().run()
Example of standalone/listening/slave process:
from smisk.core import Application, bind
class MyApp(Application):
def service(self):
self.response.write('<h1>Hello World!</h1>')
bind('hostname:1234')
MyApp().run()
It is also possible to use your own types to represent Requests and Responses. You set request_class and/or response_class to a type, before application_will_start() has been called. For example:
from smisk.core import Application, Request
class MyRequest(Request):
def from_internet_explorer(self):
return self.env.get('HTTP_USER_AGENT','').find('MSIE') != -1
class MyApp(Application):
def __init__(self):
super(MyApp, self).__init__()
self.request_class = MyRequest
def service(self):
if self.request.from_internet_explorer():
self.response.write('<h1>Good bye, cruel World!</h1>')
else:
self.response.write('<h1>Hello World!</h1>')
MyApp().run()
Current application instance, if any. Class attribute.
| See: | smisk.core.app |
|---|
Number of child processes to fork off into.
This must be set before calling run(), as it’s in run() where the forking goes down. Defaults to 0 (disabled).
New in version 1.1.0.
Default character set used to decode and encode text data. Defaults to “utf-8”.
New in version 1.1.1.
Boolean value controlling tolerance of input data handling.
When True (default) user input will be processed in a tolerant manner. I.e. if a query string encoded in iso-8859-1 is sent to an application with charset set to utf-8, the query string will still be decoded using the HTTP 1.1 (RFC 2616) fallback encoding iso-8859-1. If tolerant where False, a UnicodeDecodeError would be raised.
New in version 1.1.6.
Called when the application stops accepting incoming requests.
The default implementation does nothing.
Called just before the application starts accepting incoming requests.
The default implementation does nothing.
Handle an error and produce an appropriate response.
The built-in implementation renders error information as XHTML encoded in UTF-8 with the HTTP status code 500 (Internal Server Error).
You might override this to display a custom error response, but it is recommended you use this implementation, or at least filter certain higher level exceptions and let the lower ones through to this handler.
Normally, this is what you do:
class MyApp(Application):
def error(self, typ, val, tb):
if isinstance(val, MyExceptionType):
self.nice_error_response(typ, val)
else:
Application.error(self, typ, val, tb)
What is sent as response depends on if output has started or not: If output has started, if has_begun is True, calling this method will insert a HTML formatted error message at the end of what has already been sent. If output has not yet begun, any headers set will be discarded and a complete HTTP response will be sent, including the same HTML message described earlier.
If show_traceback evaluates to true, the error message will also include a somewhat detailed backtrace. You should disable show_traceback in production environments.
| Parameters: |
|
|---|
A HTTP request
Input stream.
If you send any data which is neither x-www-form-urlencoded nor multipart format, you will be able to read the raw POST body from this stream.
You could read x-www-form-urlencoded or multipart POST requests in raw format, but you have to read from this stream before calling any of post or files, since they will otherwise trigger the built-in parser and read all data from the stream.
Example, parsing a JSON request:
from smisk.core import *
from smisk.serialization.json import json_decode
class App(Application):
def service(self):
if request.env['REQUEST_METHOD'] == 'POST':
response('Input: ', repr(json_decode(self.request.input.read())), "\n")
App().run()
You could then send a request using curl for example:
curl --data-binary '{"Url": "http://www.example.com/image/481989943", "Position": [125, "100"]}' http://localhost:8080/
| Type: | Stream |
|---|
HTTP transaction environment.
| Type: | dict |
|---|
Reconstructed URL
For example; if you need to know if running under SSL:
if request.url.scheme == 'https':
response('Secure connection')
else:
response('Big brother is watching you')
| Type: | URL |
|---|
Parameters passed in the query string part of the URL
| Type: | dict |
|---|
Parameters passed in the body of a POST request
| Type: | dict |
|---|
Any files uploaded via a POST request
| Type: | dict |
|---|
Any cookies that was attached to the request
| Type: | dict |
|---|
Current session.
Any modifications to the session must be done before output has begun, as it will add a Set-Cookie: header to the response.
| Type: | object |
|---|
Current session id
| Type: | str |
|---|
Indicates if the request is active, if we are in the middle of a HTTP transaction
| Type: | bool |
|---|
New in version 1.1.1.
HTTP method (“GET”, “POST”, etc.).
| See: | RFC 2616, HTTP 1.1, Method Definitions |
|---|---|
| Type: | str |
New in version 1.1.2.
Limits the amount of data which Smisk normally automatically parses received in a POST or PUT request. For example uploaded files.
Only applies to payloads with a mime-type matching multipart/* – if the payload is defined as another media type, is form data or does not specify a content type – Smisk will not touch the input thus no limits apply (it’s up to the code which eventually read the input to set limits).
Setting the value to -1 or lower disables the limit. Note that this is different from max_formdata_size (which can no be disabled).
Setting the value to 0 (zero) disables automatic multipart parsing (any multipart input will be left intact/unread).
| Type: | long |
|---|---|
| Default: | 2147483648 (2 GB) |
| See: | max_formdata_size. |
New in version 1.1.2.
Limits the amount of data which Smisk will accept in a */x-www-form-urlencoded payload.
Setting the value to 0 (zero) disables automatic form data parsing (any form data input will be left intact/unread).
Note that – in contrast to max_multipart_size – this limit can not be disabled, only adjusted.
| Type: | long |
|---|---|
| Default: | 10737418 (10 MB) |
| See: | max_multipart_size |
A HTTP response.
Response headers.
| Type: | list |
|---|
Indicates if the response has begun.
Check if output (http headers & possible body) has been sent to the client.
Read-only.
True if begin() has been called and output has started, otherwise False.
| Type: | bool |
|---|
Respond with a series of byte strings.
This is equivalent of calling writelines(strings), thus if begin() has not yet been called, it will be. Calling without any arguments has no effect. Note that the arguments must be strings, as this method actually uses writelines.
Send a file to the client by using the host server sendfile-header technique.
| Parameters: |
|
|---|---|
| Raises EnvironmentError: | |
If smisk does not know how to perform sendfile through the current host server or if response has already started. |
|
| Raises IOError: | |
Begin response - send headers.
Automatically called by mechanisms like write() and Application.run().
| Raises EnvironmentError: | |
|---|---|
| if response has already started. | |
Write str bytes to out output stream.
begin() will be called if response has not yet begun.
| Parameters: |
|
|---|---|
| Raises IOError: |
Write a sequence of byte strings to the output stream.
The sequence lines can be any iterable object producing strings, typically a list or tuple of strings. There is no return value. (This interface matches that of the Python file object readlines() and writelines())
Does not add line separators or modify the strings in any way.
This method esentially calls begin() if not has_begun, then calls out.writelines(lines). The difference between calling writelines() (this method) and out.writelines() (Stream.writelines()) is that the latter will not call begin() if needed. You should always use this method instead of out.writelines(), unless you are certain begin() has been called. (begin() is automatically called upon after a service() call if it has not been called, so you can not count on it not being called at all.)
| Parameters: |
|
|---|---|
| Raises IOError: |
Find a header in the list of :attr:’headers’ matching prefix in a case-insensitive manner.
| Parameters: |
|
|---|---|
| Returns: | Index in :attr:’headers’ or -1 if not found. |
Set a cookie.
Setting a cookie effectively appends a header to headers. The cookie set will not be made available in Request.cookies.
| Parameters: |
|
|---|
Note
Setting a cookie will cause the response not to be cached by proxies or peer browsers.
See also
RFC 2109 - HTTP State Management Mechanism
A file-like I/O stream connected to the host server.
TODO
Basic session store type
For how long a session should be valid, expressed in seconds.
Defaults to 900.
| Type: | int |
|---|
Name used to identify the session id cookie.
Defaults to "SID".
| Type: | string |
|---|
Basic session store which uses files
| See: | SessionStore |
|---|
A string to prepend to each file stored in dir.
Defaults to tempfile.tempdir + "smisk-sess." – for example: /tmp/smisk-sess.
| Type: | string |
|---|
New in version 1.1.0.
A value between 0 and 1 which defines the probability that sessions are garbage collected.
Garbage collection is only triggered when trying to read a session object, so this only effects requests which involves reading sessions.
Defaults to 0.1 (10% probability)
| Type: | float |
|---|
| Parameters: |
|
|---|---|
| Raises: | InvalidSessionError if there is no actual session associated with session_id. |
| Return type: | object |
| Parameters: |
|
|---|
The URL schema, always in lower case.
| Type: | string |
|---|
| Type: | string |
|---|
| Type: | string |
|---|
| Type: | string |
|---|
Port number. 0 (zero) if unknown or not set.
| Type: | int |
|---|
| Type: | string |
|---|
| Type: | string |
|---|
| Type: | string |
|---|
Initialize a new URL from obj.
If obj is a subclass of URL, a shallow copy of obj will be returned. If obj is something else, it will be converted (if needed) into a str and parsed as it would represent a URL. (i.e. "protocol://authority:port/path...")
String representation.
By passing False (or 0 (zero)) for any of the arguments, you can omit certain parts from being included in the string produced. This can come in handy when for example you want to sanitize away password or maybe not include any path, query or fragment.
If a string is passed for one of the keyword arguments, that string is used instead of the value stored inside the URL object:
>>> from smisk.core import URL
>>> URL('http://host.name:1234/some/path').to_s()
'http://host.name:1234/some/path'
>>> URL('http://host.name:1234/some/path').to_s(host='another.host')
'http://another.host:1234/some/path'
In some cases, you may not want to include certain port numbers (80 and 443 in most cases):
>>> from smisk.core import URL
>>> url = URL('https://host:443/some/path')
>>> url.to_s(port=url.port not in (80,443))
'https://host/some/path'
| Return type: | str |
|---|---|
| Aliases: | to_str, __str__ |
Encode any unsafe or reserved characters in a given string for use in URI and URL contexts.
The difference between encode and escape is that this function encodes characters like / and : which are considered safe for rendering url’s, but not for using as a component in path, query or the fragment.
In other words: Use encode() for path, query and fragment components. Use escape() on whole URLs for safe rendering in other contexts.
Characters being escaped: $ &+,/;=?<>"#%{}|\^~[]`@: Also low and high characters (< 33 || > 126) are encoded.
| Parameters: |
|
|---|---|
| Raises TypeError: | |
if s is not a str or unicode |
|
Escape unsafe characters <> "#%{}|\^~[]`@:\033 in a given string for use in URI and URL contexts.
See documentation of encode() to find out about the differences.
| Parameters: |
|
|---|---|
| Raises TypeError: | |
if s is not a str or unicode |
|
Restore data previously encoded by encode() or escape().
Done by transforming the sequences %HH to the character represented by the hexadecimal digits HH.
| Parameters: |
|
|---|---|
| Raises TypeError: | |
if s is not a str or unicode |
|
| Aliases: | unescape |
Parses a query string into a dictionary.
>>> from smisk.core import URL
>>> print URL.decompose_query('name=Jack%20%C3%B6l&age=53')
{'age': u'53', 'name': u'Jack \xc3\xb6l'}
| Parameters: |
|
|---|