Easy to uselink | top
Poor WSGI for Python is light WGI connector with uri routing between WSGI server and your application. It have mod_python compatible request object, which is post to all uri or http state handler. The simplest way to run and test it looks like that:from wsgiref.simple_server import make_server from poorwsgi import Application app = Application('test') @app.route('/test') def root_uri(req): return 'Hello world' if __name__ == '__main__': httpd = make_server('<IP_ADDRESS>', 8080, app) httpd.serve_forever()You can use python wsgiref.simple_server for test it:
~$ python simple.pyIt has base error pages like 403, 404, 405, 500 or 501. When 500 internal server error have debug output if poor_Debug is set. And there is special debug page on
/debug-info
uri, which is available when poor_Debug is set too.
~$ poor_Debug=On python simple.pyPoor WSGI have some functions, to you can use as real http server, which could send files with right mime-type from disk, or generate directory listing. See Configuration section for more info.
~$ poor_Debug=On poor_DocumentRoot=./web poor_DocumentIndex=On python simple.pyIf you are new with it, please see fast Tutorial on this page.
Installation & Configurationlink | top
Installlink | top
Source tarballink | top
~$ wget https://pypi.python.org/packages/source/P/PoorWSGI/PoorWSGI-1.6.1.tar.gz ~$ tar xzf PoorWSGI-1.6.1.tar.gz ~$ cd PoorWSGI-1.6.1 ~# python setup.py install if you have jinja24doc and you want to install this html documentation ~# python setup.py install_html
Source from gitlink | top
~$ git clone git@github.com:PoorHttp/PoorWSGI.git or ~$ git clone https://github.com/PoorHttp/PoorWSGI.git ~$ cd PoorWSGI ~# python setup.py install if you have jinja24doc and you want to install this html documentation ~# python setup.py install_html
Install from PyPIlink | top
PoorWSGI use ordereddict which was append to collections in Python 2.7, so for Python 2.6 and less you need to install ordereddict package:~$ pip install ordereddict # only for Python2.6 and less ~$ pip install PoorWSGI
Unstable versionlink | top
Developing of next version is pushed tounstable
branch. If you want to use
this version, you must install it from git.
~$ git clone git@github.com:PoorHttp/PoorWSGI.git or ~$ git clone https://github.com/PoorHttp/PoorWSGI.git ~$ cd PoorWSGI ~$ git checkout unstable ~# python setup.py installOr you can download zip file from github.
~$ wget https://github.com/PoorHttp/PoorWSGI/archive/unstable.zip ~$ unzip unstable.zip ~$ cd PoorWSGI-unstable ~$ python setup.py installDocumentation for new version is at unstable.
Configurationlink | top
Poor WSGI is configured via environment variables with poor_* prefix.poor_BufferSizelink | top
Buffer size in bytes is size of "FIFO" like buffer, which is used for every request. Default value is 16384 bytes which is 16KiB.poor_Debuglink | top
If poor_Debug isOn
, internal server error page have debug traceback and
/debug-info
page is activate.poor_DocumentIndexlink | top
If poor_DocumentRoot is set and poor_DocumentIndex isOn
, poor WSGI can
generate document index from dictionary like real http servers. Default is
Off
.poor_DocumentRootlink | top
pooor_DocumentRoot is dictionary, which is accessible files from. Files are sent via Request.sendfile method, which is not optimized yet. Method reads data for poor_BufferSize size blocks. And of course, before files is set, rightContent-Type
from mime-type and Content-Length
headers are set.poor_LogLevellink | top
One of log level for error_log output like in Apache http server. All choices are:debug, info, notice, warn, error, alert, emerg
. Default is warn
that
means warn, error, alert and emerg type of errors are send to error file from
WSGI, which is typical error_log file of WSGI server.poor_SecretKeylink | top
If you want to use PoorSession class, as self-contained cookie, it is important to set poor_SecretKey as pass phrase for hidden function, which is call from PoorSession class. Default value is stupid string from versions and server software which is really insufficient.Poor HTTP server examplelink | top
Poor WSGI variables are system environment variables, which could be set inenviron
section in poorhttp.ini file. Only python file with application
function or class must be set in predefined variable in http
section:
[http] ... # your main python file, where app, resp. application from wsgi module # is imported application = /srv/simple.py ... [environ] # debug - internal server errror page with traceback, debug-info page poor_Debug = Off poor_DocumentRoot = /srv/public poor_DocumentIndex = On # only error alert an emerg type are log poor_LogLevel = error
uWsgi server examplelink | top
uWsgi server have more choices how is configurable. Here is it's ini file, which have oneuwsgi
section with wsgi-file
variable, where we need to set
your main python file, and lots of env variables, which is use to set
environment variables.
[uwsgi] ... # your main python file, where app, resp. application from wsgi module # is imported wsgi-file = /srv/simple.py ... # variables must be set without space between variable equation and value env = poor_Debug=On env = poor_DocumentRoot=/srv/public env = poor_SecretKey=MyApplication@Super!Secret?Password:-)
Tutoriallink | top
Returning valueslink | top
Any standard functions, resp. uri handlers got Request object as parameter, and could end with a few of choices. First, known from another frameworks are string. If string is returned, connector write that to internal buffer for you, and set DONE value as finished state.@app.route('/some/uri') def some_uri(req): ... return 'This is content for some uri'Second, standard method of return content resp. end of uri handler is write data to internal buffer and return some of state. This method is known from apaches mod_python:
@app.route('/some/uri') def some_uri(req): ... req.write('This is content for some uri') return state.DONELast way, how uri handler could be ended, is raise SERVER_RETURN object, which is known from apaches mod_python too. You can return as parametr of SERVER_RETURN object one of request state:
OK, DONE or DECLINED
or in probably more times way, one of http state like as
HTTP_MOVED_PERMANENTLY, HTTP_SEE_OTHER, HTTP_FORBIDDEN
and so on.
@app.route('/some/uri') def some_uri(req): ... if not user: raise SERVER_RETURN(state.HTTP_FORBIDDEN) req.write('This is content for some uri') return state.DONEPoor WSGI have try except blocks, where this SERVER_RETURN object is caught, and if state is not one of OK, HTTP_OK or DONE, http state handler is called.
As you can see, page data are returned as one big string, or could be write to internal buffer. You can call flush method like in mod_pytho, which send data at the moment of call of this method to WSGI server, but WSGI server can send data to client at and of your handler.
Before you send data, it could be to set
Content-Type
header of page data.
Default vaule is text/html; charset=utf-8
. You change content type by
change Request.content_type variable or via Request.headers_out object.
Content-Length
was be set automatically if data are less then
poor_BufferSize. Or you can set content length via Request.set_content_lenght
method or headers_out too.
@app.route('/some/uri') def some_uri(req) req.content_type = "text/plain; charset=utf-8" req.write('Some data') return state.DONEThere is one Request method, which write data to internal buffer, end WSGI server of course for you: sendfile. Request.sendfile send file, or part of file via internal call of Request.write method and return len of written data.
Routes and other handlerslink | top
There are too ways how to set handler. Via decorators of Application object, or method set_ where one of parameter is your handler. It is important how look your application. If your web project have one or a few files where your handlers are, it is good idea to use decorators. But if you have big project with more files, it could be difficult to load all files with decorated handlers. So that is right job for set_ methods in one file, like a route file or dispatch table.Routeslink | top
At this time, with this version, it could be set only simple routes with decorator route or method set_route. Both of methods have too parameters, uri and method, where uri is simple uri like/some/uri/for/you
and method flags
which is default METHOD_HEAD | METHOD_GET. There are other methods in state
module like METHOD_POST, METHOD_PUT etc. There is two special constants
METHOD_GET_POST which is HEAD | GET | POST, aned METHOD_ALL which is all
supported methods. If method not match, but uri is exist in internal table,
http state HTTP_METHOD_NOT_ALLOWED is return.
@app.route('/some/uri') def some_uri(req): return 'Data of some uri' def other_uri(req): return 'Data of other uri' app.set_route('/some/other/uri', other_uri, state.METHOD_GET_POST)
Group regular expression routeslink | top
As in other wsgi connectors, or frameworks if you want, there are way how to define routes with getting part of url path as parameter of handler. I call them group regular expression routes. You can use it in nice human-readable form or in your own regular expressions. Basic use is define by group name.# group regular expression @app.route('/user/<name>') def user_detail(req, name): return 'Name is %s' % nameThere are use filters define by regular expression from table Application.filters. This filter is use to transport to regular expression define by group. Default filter is
r'[^/]+'
with uni convert function. You
can use any filter from table filters.
# group regular expression with filter @app.route('/<surname:word>/<age:int>') def surnames_by_age(req, surname, age): return 'Surname is: %s and age is: %d' % (surname, age)Filter int is define by
r'-?\d+'
with convert "function" int. So age must be
number and the input parameter is int instance.There are predefined filters, for example: :int, :word, :re: and none as default filter. Word is define as
r'\w+'
regular expression, and poorwsgi
use re.U flag, so it match any Unicode string. That means UTF-8 string. For
all filters see Application.filters property or /debug-info
page.You can get copy of filters table calling Application.filters property. And this filters table is output to debug-info page. Adding your own filter is possible with function set_filter with name, regular expression and convert function which is uni by default. Next you can use this filter in group regular expression.
app.set_filter('email'<EMAIL_ADDRESS>str) @app.route('/user/<login:email>') def user_by_login(req, login): return 'Users email is %s' % loginIn other way, you can use filters define by inline regular expression. That is
:re:
filter. This filter have regular expression which you write in, and
allways uni convert function, so parametr is allways unicode.
@app.route('/<number:re:[a-fA-F\d]+>') def hex_number(req, number): return 'Number is %s that is %d so %x' % (number, int(number,16), int(number,16))
Regular expression group naminglink | top
Group names must be unique. They are store in ordered dictionary, to do wrap by their convert functions. You can named them in route definition how you can, and they can't be named same in handler parameters, but they must be only in the same ordering. Be careful to named parameters in handler with some python keyword, like class for example. If you can, you can use python "varargs" syntax to get any count of parameters in your handler function.@app.route('/test/<variable0>/<variable1>/<variable2>') def test_varargs(req, *args): return "Parse %d parameters %s" % (len(args), str(args))At last future of group regular expression routes is direct access to dictionary with req.groups variable. This variable is set from any regular expression route.
@app.route('/test/<variable0>/<variable1>/<variable2>') def test_varargs(req, *args): return "All input variables from url path: %s" % str(req.groups)
Default and http state handlerlink | top
If no route is match, there are two ways which could occur. First is call default handler if method match of course. Default handler is set with default decorator or set_default method. Parameter is only method which is default in METHOD_HEAD | METHOD_GET too. Instead of route handlers, when method does not match, 404 error was returned.@app.default(): def default(req): return 'this is default handler'Of course, before calling default handler or 404 state handler, if is poor_DocumentRoot set, poor WSGI try to find file which match uri path.
Second way how to handle 404 http state is handle http state. For this, there are http_state decorator and set_http_state method. Like as route, functions get code and method, but method is default in state
METHOD_HEAD | METHOD_GET
| METHOD_POST
. You can handle all http states instead of HTTP_OK. If you do
not handle some http state, Poor WSGI have its default handler, which is
internal_server_error, forbidden, not_found, method_not_allowed and
not_implemented.When you create your http state (error) pages, don't forget to set right status, which is set like in mod_python with set status attribute of Request object.
@app.http_state(state.HTTP_NOT_FOUND) def page_not_found(req): req.state = state.HTTP_NOT_FOUND req.write('Your request %s not found.' % req.uri) return state.DONEIf your http state (error) handler was crashed with error, internal server error was return and right handler is called. If this your handler was crashed too, default poor WSGI internal server error handler is called.
Pre and Post process functionslink | top
There are too special list of handlers. First is iter and call before each request. You can add function with pre_process decorator or add_pre_process method. Functions are called in order how is add to list. They don't return anything, resp. their return values are ignored. If they crash with error, internal_server_error was return and http state handler was called.Second list contains functions, which is called after each request. If they crash with error, internal_server_error was return and http state handler is called, but all code from pre_process and from route handler is called, and may be, it could send output to WSGI server, if content is bigger then poor_BufferSize.
@app.pre_process() def before_each_request(req): ... @app.pre_process() def after_each_request(req): ...You can use standard methods of app object, add_pre_process and add_post_process too.
Request variableslink | top
PoorWSGI has two extra classes for get arguments. From request uri, typical for GET method and from request body, typical for POST method.ore details. If this automatic parsing is disabled, a EmptyForm class is use.Application.auto_argslink | top
If auto_args is set toTrue
, which is default, Request object parse input
arguments from request uri at initialisation. There will be args
variable in
Request object, which is instance of Args class. If you want to off this
functionality, set this property to False
.Application.auto_formlink | top
If auto_form is set toTrue
, which is default, Request object parse input
arguments from request body at initialisation when request type is POST, PUT
or PATCH. There will be form
variable which is instance of FieldStorage class.
If you want to off this functionality, set this property to False
.You must do it, if you want to set your own file_callback for FieldStorage.
Application.auto_jsonlink | top
If it is True (default), method is POST, PUT or PATCH and requset content type is application/json, than Request object do automatic parsing request body to json dict variable.Application.keep_blank_valueslink | top
This property is set for input parameters to automatically calling Args and FieldStorage classes, when auto_args resp. auto_form is set. By default this property is set to0
. If it set to 1
, blank values should be interpret as
empty strings.Application.strict_parsinglink | top
This property is set for input parameter to automatically calling Args and FieldStorage classes. when auto_args resp. auto_form is set. By default this variable is set to0
. If is set to 1
, ValueError exception
could raise on parsing error. I'm sure, that you never want to set this
variable to 1
. If so, use it in your own parsing.
app.auto_form = False app.auto_args = False app.strict_parsing = 1 @app.pre_process() def auto_form_and_args(req): """ This is own implementation of req.form and req.args paring """ try: req.args = request.Args(req, keep_blank_values=app.keep_blank_values, strict_parsing=app.strict_parsing) except Exception as e: req.log_error("Bad request uri: %s", e) if req.method_number == state.METHOD_POST: try: req.form = request.FieldStorage( req, keep_blank_values=app.keep_blank_values, strict_parsing=app.strict_parsing) except Exception as e: req.log_error("Bad request body: %s", e)
Automatic convert to unicodelink | top
As variables from uri, gets with group regular expression routes, which must be in unicode to right working regular expression, all other input variables are convert to unicode by default. You can call get method on each class with your convert function of course. If you want to use internal convert function, its name is uni. Uni is function define in depend on python version. If python 2.x is use, uni encode unicode from utf-8. If python 3.x is use, default new str class is use.Request uri argumentslink | top
Request uri arguments are stored to Args class, define in poorwsgi.request module. Args is dict base class, with interface compatible methods getfirst and getlist. You can access to variables with args parameters at all time when poor_AutoArgs is set to On, which is default.@app.route('/test/get') def test_get(req) name = req.args.getfirst('name') colors = req.args.getlist('color', fce=int) return "Get arguments are %s" % uni(req.args)If no arguments are parsed, or if poor_AutoArgs is set to Off, req.args is EmptyForm instance, which is dict base class too with both of methods.
Request body argumentslink | top
Request body areguments are stored to FieldStorage class, define in poorwsgi.request module.. This class is based on FieldStorage from standard cgi module. And variables are parsed every time, when poor_AutoForm is set to On, which is default and request method is POST, PUT or PATCH. You can call it on any other methods of course, but it must exist wsgi.input in request environment from wsgi server.req.form instance is create with poor_KeepBlankValues and poor_StrictParsing variables as Args class is create, but FieldStorage have file_callback variable, which is configurable by XXX.
@app.route('/test/post', methods = state.METHOD_GET_POST) def test_post(req) id = req.args.getfirst('id', 0, int) # id is get from request uri and it # is convert to number with zero # as default name = req.form.getfirst('name') colors = req.form.getlist('color', fce=int) return "Post arguments for id are %s" % (id, uni(req.args))As like Args class, if poor_AutoForm is set to Off, or if method is no POST, PUT or PATCH, req.form is EmptyForm is instance instead of FieldStorage.
JSON requestlink | top
In the first place JSON request are from AJAX. There are automatic JSON parsing in Request object, which parse request body to JSON variable. This parsing starts only when Application.auto_json variable is set to True (default) and if content type of POST, PUT or PATCH request is application/json. Then request body is parsed to json property.import json @app.route('/test/json', methods=state.METHOD_POST | state.METHOD_PUT | state.METHOD_PATCH) def test_json(req): for key, val in req.json.items(): req.error_log('%s: %v' % (key, str(val))) req.content_type = 'application/json' return json.dumps({'Status': '200', 'Message': 'Ok'})JQuery AJAX request could look like this:
$.ajax({ url: '/test/json', type: 'put', accepts : {json: 'application/json', html: 'text/html'}, contentType: 'application/json', dataType: 'json', data: JSON.stringify({ test: 'Test message', 'count': 42, 'note': null }), success: function(data){ console.log(data); }, error: function(xhr, status, http_status){ console.error(status); console.error(http_status); } });
File uploadinglink | top
By default, pythons FieldStorage, so poorwsgi.FieldStorage too, store files somewhere to /tmp dictionary. This works in FieldStorage, which calls TemporaryFile. Uploaded files are accessible like another form variables, but.Any variables from FieldStorage is accessible with __getitem__ method. So you can get variable by
req.form[key]
, which gets FieldStorage instance. This
instance have some another variables, which you can test, what type of
variable is.
@app.route('/test/upload', methods = state.METHOD_GET_POST) def test_upload(req): # store file from upload variable to my_file_storage file if 'upload' in req.form and req.form['upload'].filename: with open('my_file_storage', 'w+b') as f: f.write(req.form['upload'].file.read())
Your own file callbacklink | top
Sometimes, you want to use your own file_callback, because you don't want to use TemporaryFile as storage for this upload files. You can do it with simple addingfile
class. But if you want to do in Python 3.x, you must add
io.FileIO class, cause file class not exist in Python 3.x.
from poorwsgi import Application, state, request from sys import version_info if version_info.major >= 3: from io import FileIO file = FileIO app = Application('test') app.auto_form = False # disable automatic request body parsing - IMPORTANT ! @app.pre_process() def auto_form(req): if req.method_number == state.METHOD_POST: # store upload files permanently with their right file names req.form = request.FieldStorage( req, keep_blank_values=app.keep_blank_values, strict_parsing=app.strict_parsing, file_callback=file)As you can see, this example works, but it is so bad solution of your problem. Little bit better solution will be, if you store files only if exist and only to special separate dictionary, which could be configurable. That you need use factory to create file_callback.
from poorwsgi import Application, state, request from sys import version_info if version_info.major >= 3: from io import FileIO file = FileIO app = Application('test') class Storage(file): def __init__(self, directory, filename): self.path = directory + '/' + filename if os.access(self.path, os.F_OK): raise Exception("File %s exist yet" % filename) super(Storage, self).__init__(self.path, 'w+b') class StorageFactory: def __init__(self, directory): self.directory = directory if not os.access(directory, os.R_OK): os.mkdir(directory) def create(self, filename): return Storage(self.directory, filename) app.auto_form = False # disable automatic request body parsing - IMPORTANT ! @app.pre_process() def auto_form(req): """ Own implementation of req.form paring before any POST request with own file_callback. """ if req.method_number == state.METHOD_POST: factory = StorageFactory('./upload') try: req.form = request.FieldStorage( req, keep_blank_values=app.keep_blank_values, strict_parsing=app.strict_parsing, file_callback=factory.create) except Exception as e: req.log_error(e)
Application / User optionslink | top
Like in mod_python Request, Poor WSGI Request have get_options method too. This method return dictionary of application options or variables, which start withapp_
prefix. This prefix is cut from options names.
[uwsgi] # uwsgi config example ... env = app_db_file = mywebapp.db # variable is db_file env = app_tmp_path = tmp # variable is tmp_path env = app_templ = templ # variable is templAnd you can get these variables with get_options method:
config = None @app.pre_process() def load_options(req): global config if config is None: config = req.get_options() req.config = config @app.route('/options') def list_options(req): for key, val in req.config.items(): req.write(key + '\t: '+ val)Output of application url /options looks like:
db_file : mywebapp.db tmp_path : tmp templ : templAs you can see, you can store your variables to request object. There are few reserved variables for you, which poorwsgi never use, and which are None by default:
req.config
- for your config objectreq.logger
- for your special logger object or logger functionreq.user
- for user object, who is loginreq.app_
- as prefix for any your application variableSo if you want to add any other variable, be careful to named it.
from time import ctime log = open('app.log', 'w+') def my_logger(msg) log.write(ctime() + ': ' + msg + '\n') @app.pre_process() def set_logger(req): req.logger = my_logger @app.route('/test') def test(req): req.logger('test call') ...
Headers and Sessionslink | top
Headerslink | top
We talk about headers in a few paragraph before. Now is time to more information about that. Request object have headers_in attribute, which is instance of wshiref.headers.Headers. This headers contains request headers from client like in mod_python. You can read it as you can.Next to it, there are two output attributes headers_out and err_headers_out. Both of that are instance of Headers class from request module. The Headers class is child of wsgiref.headers.Headers class with little additional. By default there is
X-Powered-By
header set to "Poor WSGI for Python" and
add method raise exception if you try to set more same keys without
Set-Cookie
.Different before headers_out and err_headers_out is, that err_headers_out is use in internal http state handlers like in mod_python.
@app.route('/some/uri') def some_uri(req): xparam = int(req.headers_in.get('X-Param', '0')) req.headers_out.add('My-Param', xparam * 2) ...
Sessionslink | top
Like in mod_python, in poor WSGI is session class PoorSession. It is self-contained cookie which have data dictionary. Data are sent to client in hidden, bzip2ed, base64 encoded format. In read this session, expires value are check from data, so client can't change it in simple way. That is important to right set poor_SecretKey variable which is used in class by hidden function.from poorwsgi import Application, state, redirect from poorwsgi.session import PoorSession from os import urandom app = Application('test') app.secret_key = urandom(32) # random secret_key def check_login(fn): def handler(req): cookie = PoorSession(req) if 'passwd' not in cookie.data: # expires or didn't set req.log_error('Login cookie not found.', state.LOG_INFO) redirect(req, '/login', text='Login required') return fn(req) return handler @app.route('/login', method = state.METHOD_GET_POST) def login(req): if req.method == 'POST': passwd = req.form.getfirst('passwd', fce=str) if passwd != 'SecretPasswds': req.log_error('Bad password', state.LOG_INFO) redirect(req, '/login', text='Bad password') cookie = PoorSession(req) cookie.data['passwd'] = passwd cookie.header(req, req.headers_out) redirect(req, '/private/uri') return 'some html login form' @app.route('/private/uri') @check_login def private_uri(req): return 'Some private data' @app.route('/logout') def logout(req): cookie = PoorSession(req) cookie.destroy() cookie.header(req, req.headers_out) redirect(req, '/login')
Debugginglink | top
Poor WSGI have few debugging mechanism which you can to use. First, it could be good idea to set up poor_Debug variable. If this variable is set, there are full traceback on error page internal_server_error with http code 500.Second property of this variable is enabling special debug page on
/debug-info
url. On this page, you can found:*
full handlers table with requests, http methods and handlers which are
call to serve this requests.*
http state handlers table with http state codes, http methods and handlers
which are call when this http state is returned.*
request headers table from your browser when you call this debug request*
poor request variables, which are setting of actual instance of Poor WSGI
configuration variables.*
application variables which are set like a connector variables but with
app_ prefix.*
request environment, which is set from your wsgi server to wsgi
application, so to Poor WSGI connector.Profilinglink | top
If you want to profile your request code, you can do with profiler. Poor WSGI application object have methods to set profiling. You must only prepare runctx function, which is call before all your request. From each your request will be generate .profile dump file, which you can study.If you want to profile all process after start your application, you can make file, which profile importing your application, which import Poor WSGI connector.
import cProfile # this import your application, which import Poor WSGI, so you can profile # first server init, which is do, when server import your application. # don'ŧ forget to import this file instead of simple.py or your # application file cProfile.runctx('from simple import *', globals(), locals(), filename="log/init.profile") # and this sets profiling of any request which is server by your # web application app.set_profile(cProfile.runctx, 'log/req')When you use this file instead of your application file, simple.py for example, application create files in log directory. First file will be init.profile from first import by WSGI server. Other files will look like req_.profile, req_debug-info.profile etc. Second parameter of set_profile method is prefix of output file names. File name are create from url path, so each url create file.
There is nice tool to view this profile files runsnakerun. You can download from http:/www.vrplumber.com/programming/runsnakerun. Use that is very simple just open profile file:
$~ python runsnake.py log/init.profile $~ python runsnake.py log/req_.profile
Few word at the endlink | top
Once upon a time, there was a King. Ok there was a Prince. Oh, may by, there was not a prince, but probably, there was a Programmer, hmm ok, programmer. And this programmer know apaches mod_python. Yes it was very very bad paragon, but before python, he was programing in php. So mod_python was be big movement to right direction at that times.He was founding how he can write, and host on server python applications. And as he know some close-source framework, which works right, he write some another, similar for his use. That is base of Poor Publisher. But WGSI was coming so he had idea, to write some new backend for his applications. That is base of Poor HTTP and Poor WSGI.
 It is better way, but that's not right way. After some time, he divide these too projects to Poor WSGI and Poor HTTP projects. But there is bad concept in Poor WSGI framework, which is not framework in fact. So he look for another projects, and see how could be nice to create WSGI application for user. That is time when Poor WSGI is rewritten to library type code, and application is callable class with some nice route and other methods - decorators.
This is story of one programmer and his WSGI framework, which is not framework in fact, because, it knows only handle uri request with some mod_python compatibility layer. As you can see, there are some ways, how this project can go. It's author, programmer use it on his projects, and it would be so nice, if there are more programmers then he, which use this little project, let's call it WSGI connector.
If you have any questions, proposals, bug fixes, text corrections, or any other things, please send me email to mcbig at zeropage.cz or you can create issue on GutHub: https://github.com/PoorHttp/PoorWSGI/issues Thank you so much.
ChangeLoglink | top
For release history or difference of releases, you can use git diff, diff log, git2cl tool or you can see ChangeLog from source code or on git repository web. See:https://github.com/PoorHttp/PoorWSGI/blob/master/doc/ChangeLog
Simple.pylink | top
It is published simple.py application test file. You can download it, study it test or use it as you can. See:https://github.com/PoorHttp/PoorWSGI/blob/master/simple.py


Tailored Designs
Our designs are an outcome of understanding client requirement, thorough research and then executing a customized design to replicate exactly what our clients are looking for.
We offer wellness solutions for trouble-free and delightful play, sport and environment experience. We offer varieties of Child Friendly Playground equipment, Play flooring, Sports flooring, Indoor & Outdoor Fitness equipment to Clean Air and Water through Ozone generators.
Hi5 Solutions comprise of Five elements right advise, timely response, quality, after sales service and commitment. We showcase products which blends technology and cost to enhance your Brand value. We strive to redefine wellness.
Our designs are an outcome of understanding client requirement, thorough research and then executing a customized design to replicate exactly what our clients are looking for.
We have solutions for every budget bracket, because we believe that playing is a necessity and not a luxury. From basics to advanced, we have designs and solutions for every level of requirement.
Our experts’ team ensures smooth and speedy execution with transparent communication and continuous coordination.
We don’t just deliver products, but create experiences. Our team is always ready to solve your queries or assist you in any way as required. Because for us, service comes first.
- Playground Equipment
- Outdoor Fitness
- Garden Add-ons
Hi5 Solutions is committed to provide child friendly playground equipment. Our playground equipment not only increases children’s physical and mental growth, but also adds aesthetic value to the surrounding. These playground equipment can be complimented with additions of Outdoor Fitness equipment, EPDM rubber play flooring, Rubber tiles, Artificial Grass alongwith Benches and Dustbins.
A useful amenity for Builders, School, Architect, Landscape consultant, Municipal Parks, Housing Society, Residential colony, Corporate Social Responsibility.
- Play Flooring
- Sports Flooring
Hi5 Solutions introduces Hi5Play of Play and Sports flooring. A proper flooring not only provide safety aspect but also inspires players to play in a professional manner. Play floorings consists of EPDM rubber flooring, Rubber Tiles, Artificial Grass and Sports Flooring is has options of Acrylic, Vynil, PU, EPDM and Wooden Flooring. Sports Flooring can be built for various sports like Badminton, Lawn Tennis, Basketball, Volleyball, Multipurpose court, Gymnasium and more.. Builders, Education Institution Architect, Landscape Consultants, Housing Society, Residential Colony, PSU, Corporate are potential segments for Play and Sports flooring.
Know More...
- Ozone Generator
- Foot Sanitizer Dispenser Stand
Healthy environment leads to healthy life. Hi5 Solutions provides Ozone Generator which not only reduces bacteria but also removes smell. Our solution reduces dependency on chemicals and other disinfectants. We have complete options in ozone generator for a healthy environment. Ozone generator are useful utility for Health centers, Hotels, Resorts, Clubs, Malls, Food Processing units, Pharma units.
Know More...Vasai
Maharashtra, India
Our mission is to help our customers have a relaxing environment with best quality products and services. With over 25 years of experience in this field, our team is always ready to provide valuable inputs from their site visits to choice of materials as per your budgets and preferences.


New Gem Generator
newgem
What
Quickly bundle any Ruby libraries into a RubyGem and share it with the world, your colleagues, or perhaps just with yourself amongst your projects.
RubyGems are centrally stored, versioned, and support dependencies between other gems, so they are the ultimate way to bundle libraries, executables, associated tests, examples, and more.
Within this gem, you get one thing – newgem
– an executable to create your own gems. Your new gems will include designated folders for Ruby code, test files, executables, and even a default website page for you to explain your project, and which instantly uploads to RubyForge website (which looks just like this one by default)
Installing
The newgem
application is distributed itself as a RubyGem and is available immediately after installation.
sudo gem install newgem
Alternately, download the gem and install manually.
The basics
Go to the folder where you want to create your new gem folder structure, and run the newgem
command to generate your gem scaffolding.
$ cd ~/ruby_projects $ newgem wizzo create create config create doc create lib create log create script create tasks create test create tmp create lib/wizzo create History.txt create License.txt create Rakefile create README.txt create setup.rb create lib/wizzo.rb create lib/wizzo/version.rb create config/hoe.rb create config/requirements.rb create log/debug.log create tasks/deployment.rake create tasks/environment.rake create tasks/website.rake create test/test_helper.rb create test/test_wizzo.rb dependency install_website create website/javascripts create website/stylesheets exists script exists tasks create website/index.txt create website/index.html create script/txt2html force tasks/website.rake dependency plain_theme exists website/javascripts exists website/stylesheets create website/template.html.erb create website/stylesheets/screen.css create website/javascripts/rounded_corners_lite.inc.js dependency install_rubigen_scripts exists script create script/generate create script/destroy create Manifest.txt readme readme Important ========= * Open config/hoe.rb * Update missing details (gem description, dependent gems, etc.)
As of 0.10.0 – you can generate test::unit or rspec test stubs via the -T
or --test-with
options. For example, -T rspec
generates a spec
folder with some test stubs.
Setup
Now modify the constants at the top of config/hoe.rb, with your name, email and the location where you’ll host your website for the gem. The defaults are tied to RubyForge for uploading the gems and the website (see below).
Create code and tests
Then create your libraries (files in lib
) and your tests (files in test
that look like test_TESTNAME.rb
). James Edward Gray II did a nice video on test-driven design, that’s worth watching if TDD is new to you.
If you create any new files, you need to manually add them to the Manifest.txt. Alphabetical order is optional, but it will make the results of rake check_manifest
look clean if you keep them ordered. If a file is not in the Manifest.txt it will not be included in the gem when you package and release it.
Executables
You can include executable Ruby applications in your gem, which will be accessible on Windows and Unix/Linux/MacOS, by creating scripts in the bin
folder. When the gem is deployed by users, these executables will be automatically placed within their path.
Website
The final step before releasing your gem to the world is the all-important website. Edit the file website/index.txt
using Textile/Redcloth syntax. Syntax highlighting is also supported (see below). If you need more website pages, create more txt files in the website folder.
Run the rake task rake website_generate
to convert all your website txt files into html files.
NOTE: Currently, the initial index.txt
file includes my details not yours. Currently you need to change this manually.
If you don’t want a website, remove the website
related files from the Manifest.txt.
Change the gems version number
The version number is set in the file lib/#gem name#/version.rb
. Update it as appropriate with major, minor and bug fix numbers. This value will be used when generating your website, for example.
Check the manifest
Manifest: a customs document listing the contents put on a ship or plane.
Similarly here, a manifest is the log of the files to be packaged into a gem. If its not in the Manifest.txt
file, the users won’t get it.
Before you package your gem, you can compared the list of files in your gem folder, with the Manifest.txt:
rake check_manifest
The results show a diff of the two.
Package and test locally
Before releasing a new version of a gem, it is a great idea to install the gem locally and do some sanity checks. You know, to limit the chance of you looking like a noob.
rake local_deploy
This generates the website html files into your website folder, and locally installs the gem, ready for testing and local use.
Now pretend to be a user, and do some tests – especially of new functionality – so you are comfortable all the files have been packaged up, and you haven’t missed anything in the Manifest.txt
.
One set of tests you should do is to repeat any tutorials you include in your website. If your gem is dependent on other gems that are rapidly changing, its possible your tutorial might be invalid even if your unit tests are successful. Best you find any errors before the users start emailing you!
Releasing your gem to the world
Once you’re ready for release there are some final steps.
Setup your environment to upload to RubyForge.
There are several steps you need to perform initially to setup your environment for uploading gems to RubyForge.
Document changes in History.txt
Between each version of your gem, you probably changed something. You should document this in the History.txt
file. For each new release, you need to add two paragraphs that look like this:
== 0.5.4 14/4/2007 * 1 major improvement * 150% more Wizzos * 2 bug fixes * Wizzos are the proper colour * You only get Wizzos when you ask for them
The two paragraphs will be automatically picked up by the following release process and documented against the release on RubyForge site. To see an example of the end result, look at the History page for newgem.
The History.txt notes for your first release have already been started for you.
Release the gem and upload the website and rdocs
Run rake deploy VERSION=X.Y.Z
after you’ve done all these steps. It does the following:
- Uploads your website to rubyforge
- Uploads your rdocs to rubyforge
- Packages and uploads your gem to RubyForge
It can take an hour or two before new gem releases are available via the gem installer. But when they are ready, everyone will be able to download and install your gem using:
sudo gem install #gem_name#
If your GEM_NAME and RUBYFORGE_PROJECT name are the same, then:
- http://RUBYFORGE_PROJECT.rubyforge.org is your website, and
- http://RUBYFORGE_PROJECT.rubyforge.org/rdoc is your rdocs
If they are different, then:
- http://RUBYFORGE_PROJECT.rubyforge.org/GEM_NAME is your website, and
- http://RUBYFORGE_PROJECT.rubyforge.org/GEM_NAME/rdoc is your rdocs
Bonus tasks thanks to Hoe
Your gem uses the Hoe gem to provide a dozen or so useful rake tasks for managing your gem, such as release
, check_manifest
and publish_docs
.
See them all with:
rake -T
Remember, the Rakefile is yours to extend as you please with more rake tasks, such as the website
tasks which are already added.
For more information about each task, see the Hoe README
Related articles
- Original blog article and tutorial
- Tutorial: Publishing RubyGems with Hoe by Geoffrey Grosenbach
- Using New Gem Generator in Windows by Jorge Cangas
- Building a Ruby Gem by Joseph Pecoraro (includes a Problems/Troubleshooting section!!)
Dr Nic’s Blog
http://www.drnicwilliams.com – for future announcements and
other stories and things.
Forum
http://groups.google.com/group/new-gem-generator
How to submit patches
Read the 8 steps for fixing other people’s code and for section 8b: Submit patch to Google Groups, use the Google Group above.
You can fetch the source from either:
- rubyforge: http://rubyforge.org/scm/?group_id=2340
git clone git://rubyforge.org/newgem.git
git clone git://github.com/drnic/newgem.git
Build and test instructions
cd newgem rake test rake install_gem
License
This code is free to use under the terms of the MIT license.
Contact
Comments are welcome. Send an email to Dr Nic Williams.
Dr Nic, 24th September 2008
Theme extended from Paul Battley


Q/Z effects pedals was founded by Quinn Schwartz in November, 2016 in Portland Oregon. All of our pedals are custom built using high quality components. Contact us at qzpedals@gmail.com


accordion
modal-fixed
mouse-watch
render-watch
resize-watch
user-agent
page-scroll
flex-slider
touch-watch
tween-animation


Connect your users in real time with just a few lines of code - messages you publish are seamlessly broadcast to other users or internal services.


You can push and pull data from a Nimbits Server, be it your own instance or the public server using a collection of Web Services. The web services allows you to create data points, categories, and record data to your points in many different ways. In general, all web service respond to simple POST and GET actions and respond with text, or JSON data.
You can program against the web services, or use them directly by putting the url to a service in a spreadsheet like Excel or Google Docs.
Each web service call must be properly authenticated. This can be done simply by providing your email address and Nimbits client key.
There is a helpful service you can try posting or getting parameters to: /service/authApi which will respond with the work true or fall (and a 200 OK response) if the values your posting were correctly authenticated.
Start any web request with these parameters in the post or get command:
<EMAIL_ADDRESS>@Deprected Warning: use key instead of the old 'secret' param. 'secret= has been deprecated


I would not recommend Dramamine to anyone looking for a good time, or even a profound psychedelic experience. It has the most unusual and intense effects of anything I have ever put into my body, and I feel that most people would not enjoy, or even be safe under these effects. This drug is a delriant, meaning that it is incredibly hard to discern what is real and what isn't.
About two hours before dosing, I took two 10mg Ritalin pills in order to stay awake for the experience, and remember as much as possible. At about 6 o'clock, I took 20 50mg generic Dramamine pills (Dimenhydrinate). I noticed the first affects 20 minutes after uptake. My body felt heavy and awkward, and my mouth was extremely dry. After a half hour, I walked into the hallway to talk to some people on my hall (I am very casual about my drug use, and told everyone what was going on). Conversing was a lot harder than usual. I spoke in a very quiet voice, had a hard time articulating my thoughts, and other people seemed to drag on a lot more than usual. At one point, I asked my friend what the tiny shimmering runes on his shirt said, and everyone just laughed (obviously I was the only one seeing this). After this, I decided it would be a good idea to go back into my room and relax for a bit.
At this point, all sense of time was completely lost and distorted, so I am sorry that I cannot tell you when things are happening.  The walls were “melting”, my bed was turning into moving patterns, etc. Most distinguished from other psychedelic experiences were the actual 3D constructs I saw. There was this substance that I can only describe as colorless Jello mixed with lightning arcs. It was crawling in my hands, and I could control it's growth with my mind, in addition to sticking it to other surfaces. Tiny bubbles that seemed to be made of the same substance were all over my hands, or any part of my body that I looked at closely enough. The hair on my arms grew out at impossible angles and seemed to be more like magnetic iron dust than anything else. These were the most minor hallucinations of the night.
After this, I began hearing new lyrics to the music I was hearing, that either had to do with the song's subject, or what I was currently thinking about. The uncanny part was that it sounded so natural and real, just like the rest of the song. I believe it was about an hour after dosing (cant really be sure) that I made the trek downstairs to try to get a drink from the dorm's convenience store. I brought a vitamin water up to the counter, and it seemed like it took the cashier about two minutes to acknowledge my presence. Eventually, he asked me for a dollar fifty, but I only had one one dollar bill, and no change. I had plenty of higher bills, but it didn't occur to me that I could pay with those, so I just shook my head and said “I can't do this” and walked back to my room. Luckily the cashier was very nice and just said “it's ok, that's fine.”
I got back to my room alright, and this was when the really weird stuff started happening. The hallucinations from before were still around, but more intense. In addition to this, people started appearing and disappearing from my room. Unfortunately, I do not remember all the specifics of what happened, but here are a few samples:
At one point, I was having a perfectly natural and purposeful conversation with a woman I had never seen before, who was kneeling in prayer on my bed, while I sat at my computer. At some point she disappeared, but there were plenty of other people to keep me company. I also remember figuring out how weird and lonely it sounded when I spoke aloud, and that telepathic communication was just as effective, and also wouldn't weird out someone walking by my room. I have never purported to have telepathy or anything like it before, but it seemed as natural as anything.
Sometime later or earlier, my roommate and his friend came back into my room. At the same time, I was laying in my bed looking at the wall, but also intently staring at them. When they spoke, there was a huge delay between when their lips moved and when I heard what they said, and I had no idea what they were talking about. I asked my roommate if this actually happened, and he said that I was acting normal, and they did both come in, I was just a bit quiet. I also figured out that I saw the exact same thing with my eyes open or closed. Luckily, I was coherent enough not to test this outside of my room. While I highly doubt this is actually what was happening, it was very fascinating and fun to have so many psychic powers.
Many other strange things occurred, but it is very hard to recall anything outside of what I have mentioned. After the trip, some very unpleasant side effects occurred. My muscles all tightened, and occasionally tremored. The dehydration was very intense and lasted into the next day. Also, I experienced minor hand shaking for the next two days (a little worrying, because I didn't read about anyone else experiencing this, but it went away). I woke up with a bit of a headache, with a bit of delirium still hanging around.
I now believe that all of the unpleasant physical side effects are from a dangerously low potassium level and dehydration. I believe that there are many positive, relatively safe drugs out there. Dramamine (Dimenhydrinate) is not one of them. The only reason you should try this is if you are looking for an experience unlike anything else in this world, and are prepared to deal with everything that comes along with it.
Experience Reports are the writings and opinions of the individual authors who submit them.
Some of the activities described are dangerous and/or illegal and none are recommended by Erowid.


WEEK 28 SATURDAY
Year 1 (Year 2)
FIRST READING Romans 4:13.16-18
“In hope he believed against hope.”
A reading from the Letter of Saint Paul to the Romans
Brethren: The promise to Abraham and his
descendants, that they should inherit the world, did not come through the law but
through the righteousness of faith. That is why it depends on faith, in order
that the promise may rest on grace and be guaranteed to all his descendants--
not only to the adherents of the law but also to those who share the faith of
Abraham, for he is the father of us all, as it is written, "I have made
you the father of many nations" --in the presence of the God in whom he
believed, who gives life to the dead and calls into existence the things that
do not exist. In hope he believed against hope, that he should become the
father of many nations; as he had been told, "So shall your descendants
be."
The word of the Lord
RESPONSORIAL PSALM Psalm 105:6-7.8-9.42-43 (R. 8a)
R. The Lord remembers his covenant for ever.
O children of Abraham, his servant, O
descendants of the Jacob he chose, he, the LORD, is
our God; his judgments are in all the earth.
R. The Lord remembers his covenant for ever.
He remembers his covenant for ever: the promise he ordained
for a thousand generations, the covenant he made with Abraham, the oath he
swore to Isaac.
R. The Lord remembers his covenant for ever.
For he remembered his holy word, spoken to
Abraham his servant. So he brought out his people with joy, his
chosen ones with shouts of rejoicing.
R. The Lord remembers his covenant for ever.
FIRST READING Ephesians 1:15-23
“He made Christ the head over all things for the Church, which is his body.”
A reading from the Letter of Saint Paul to the Ephesians
Brethren: Because I have heard of your faith in the
Lord Jesus and your love toward all the saints, I do not cease to give thanks
for you, remembering you in my prayers, that the God of our Lord Jesus Christ,
the Father of glory, may give you a spirit of wisdom and of revelation in the
knowledge of him, having the eyes of your hearts enlightened, that you may know
what is the hope to which he has called you, what are the riches of his
glorious inheritance in the saints, and what is the immeasurable greatness of
his power in us who believe, according to the working of his great might which he accomplished in Christ when he
raised him from the dead and made him sit at his right hand in the heavenly
places, far above all rule and authority and power and dominion, and above
every name that is named, not only in this age but also in that which is to
come; and he has put all things under his feet and has made him the head over
all things for the church, which is his body, the fullness of him who fills all
in all.
The word of the Lord
RESPONSORIAL PSALM Psalm 8:2-3a.4-5.6-7 (R. see 6a)
R. You have given your Son power over the works of your hands.
O LORD, our God, how majestic is your name through all
the earth! Your majesty is set above the heavens. From the mouths of children
and of babes you fashioned praise.
R. You have given your Son power over the works of
your hands.
When I see the heavens, the work of your fingers,
the moon and the stars which you arranged, what is man that you should keep him
in mind, the son of man that you care for him?
R. You have given your Son power over the works of
your hands.
 You have given your Son power over the works of
your hands.
R. Alleluia. The Spirit of truth will bear witness to me, says the Lord; and you also are witnesses. R. Alleluia.
GOSPEL Luke 12:8-12
“The Holy Spirit will teach you in that very hour what you ought to say.”
A reading from the holy Gospel according to Luke
At that time: Jesus said to his disciples, “Every
one who acknowledges me before men, the Son of man also will acknowledge before
the angels of God; but he who denies me before men will be denied before the
angels of God. And every one who speaks a word against the Son of man will be
forgiven; but he who blasphemes against the Holy Spirit will not be forgiven.
And when they bring you before the synagogues and the rulers and the
authorities, do not be anxious how or what you are to answer or what you are to
say; for the Holy Spirit will teach you in that very hour what you ought to
say.”
The Gospel of the Lord


How to configure Portworx volume replication
Overview
Portworx is a cloud-native storage solution that is now available as an integration with our OpenShift offering. This article describes how to configure replication for Portworx volumes.
Intended audience
This article assumes you have access to a Portworx integrated OpenShift 3.11 cluster and that you have cluster-admin rights. It also assumes familiarity with oc
, the OpenShift command-line client. For one of the steps you will also need to have jq
installed.
If you're interested in a free 30 day trial of Portworx, raise a Service Request via the My Calls section of the UKCloud Portal.
Replication
Portworx runs as a container on all compute nodes in a cluster and stores volume data on block storage attached to each of these nodes. This volume data can be synchronously replicated between nodes to provide redundancy and increase read speed using parallelism across nodes.
Configuring the replication factor
The replication factor of a volume is determined by the storage class from which a persistent volume claim is created. Use the following parameter to set the replication factor to a value between 1 and 3 within the storage class spec:
parameters:
repl: "2"
If a pod is running on a node that becomes isolated, the pod can be scheduled to an alternate node provided there is a replica on that same node.
The following example shows the spec for a storage class with a replication factor of 3:
kind: StorageClass
apiVersion: storage.k8s.io/v1beta1
metadata:
name: portworx-repl3
provisioner: kubernetes.io/portworx-volume
parameters:
repl: "3"
Modifying a volume replication factor
You can increase or decrease the replication factor for a Portworx volume after it has been created using the Portworx command line tool pxctl
. For the purpose of this article, we will use a persistent volume claim named pvc-repl2.
Before proceeding, identify the volume name for the persistent volume claim and store this to an environment variable so it can be referenced in multiple commands:
$ VOLUME=$(oc get pvc pvc-repl2 -o custom-columns=VOLUME:.spec.volumeName --no-headers) $ echo $VOLUME pvc-e15d82b2-ed46-11e9-8422-fa163e52fd0e
Note
The
pxctl
binary is available within the Portworx container, therefore the easiest way to execute commands against the Portworx cluster is to do so remotely using theoc exec
command.To reduce command complexity, we will set an environment variable named PX_POD containing the name of a Portworx pod so we can re-use it throughout the article.
$ PX_POD=$(oc get pods -l name=portworx -n kube-system -o jsonpath='{.items[0].metadata.name}') $ echo PX_POD portworx-7cqq6
Verify the current replication factor and the IPs of the nodes storing the replicas:
$ oc exec $PX_POD -n kube-system -- /opt/pwx/bin/pxctl volume inspect $VOLUME | grep -E 'HA|Node' HA : 2 Node : <IP_ADDRESS> (Pool 0) Node : <IP_ADDRESS> (Pool 0)
To replicate the volume to an additional node, we need to determine its Portworx node ID. To do so we will export the ID and IP for each node. In this case, by eliminating the IPs returned in the previous step we can identify that the remaining node ID is 6dcb56bc-9402-41ea-b819-56f2c9e1c742:
$ oc exec $PX_POD -n kube-system -- /opt/pwx/bin/pxctl cluster list -j | jq '(.cluster.Nodes[] | {"ID": .Id, "IP": .DataIp})' { "ID": "6dcb56bc-9402-41ea-b819-56f2c9e1c742", "IP": "<IP_ADDRESS>" } { "ID": "433f83c2-32d1-458e-a71c-b0d56cb29023", "IP": "<IP_ADDRESS>" } { "ID": "a1993b47-2c97-4847-94d7-3eb79962d3cc", "IP": "<IP_ADDRESS>" }
You can then replicate the volume to the remaining node:
$ oc exec $PX_POD -n kube-system -- /opt/pwx/bin/pxctl volume ha-update --repl=3 --node 6dcb56bc-9402-41ea-b819-56f2c9e1c742 $VOLUME Update Volume Replication: Replication update started successfully for volume pvc-e15d82b2-ed46-11e9-8422-fa163e52fd0e
Verify that the volume has been replicated to the additional node:
$ oc exec $PX_POD -n kube-system -- /opt/pwx/bin/pxctl volume inspect $VOLUME | grep -E 'HA|Node' HA : 3 Node : <IP_ADDRESS> (Pool 0) Node : <IP_ADDRESS> (Pool 0) Node : <IP_ADDRESS> (Pool 0)
You can remove a replica from a node by specifying the node ID and reducing the replication factor:
$ oc exec $PX_POD -n kube-system -- /opt/pwx/bin/pxctl volume ha-update --repl=2 --node 6dcb56bc-9402-41ea-b819-56f2c9e1c742 $VOLUME Update Volume Replication: Replication update started successfully for volume pvc-e15d82b2-ed46-11e9-8422-fa163e52fd0e
Further reading
Feedback
If you find a problem with this article, click Improve this Doc to make the change yourself or raise an issue in GitHub. If you have an idea for how we could improve any of our services, send an email to feedback@ukcloud.com.


Here's a breakdown of your code:
{{ results['analysis'][n]['attribute'] }}
{{ results['analysis'][n]['reason'] }}
{{ n }}
has {{ v }} characters!
Used {{ v }} times!


--- title: "Dattafest: Topology and Combinatorics" layout: standalone css: "datta-fest" ---
A hybrid symposium on Topology and Combinatorics will be organized by the Department of Mathematics, Indian Institute of Science on Thursday, 28 July, 2022 on the occasion of the superannuation of Prof. Basudeb Datta.
All lectures will be in hybrid mode, with some delivered in person and streamed online and others streamed to the venue as well as online.
This is part of a three-day symposium on the occasion of superannuation of three of our faculty members.
If you wish to attend either in-person or online, please register by July 15, 2022. Links for the lectures will be sent to the registered participants. If you are at IISc, please also join the Microsoft Teams Team.
| Time | Speaker | Title |
|---|---|---|
| 09:30 am – 10:15 am | Bhaskar Bagchi (ISI Bangalore) | The uniqueness conjecture [Video] |
| 10:20 am – 11:05 am (online) | Benjamin Burton (University of Queensland, Australia) | The power of cheap tricks: Using combinatorial structure in topological software [Video] |
| COFFEE BREAK | ||
| 11:30 am – 12:15 pm (online) | Satoshi Murai (Waseda University, Japan) | Stackedness, tightness, and commutative algebra [Video] |
| 12:20 pm – 1:05 pm | Soumen Sarkar (IIT Madras) | On triangulations of a class of quasitoric manifolds [Video] |
| LUNCH | ||
| 2:10 pm – 2:40 pm (slides*) | Wolfgang Kühnel (University of Stuttgart) | Generalized Heawood numbers [Video] |
| 2:45 pm – 3:30 pm | Jonathan Spreer (University of Sydney, Australia) | An algorithm to compute the crosscap number of a knot [Video] |
| COFFEE BREAK | ||
| 4:00 pm onwards | Reminiscences |
∗ The slides of Wolfgang Kühnel will be presented by Biplab Basak and Nitin Singh.
The registration process is for all three symposiums. Please register by July 15, 2022 if you wish to attend either in-person or online. If you are at IISc, please also join the Microsoft Teams Team.


Name:
E-mail:
mobile:
Password:
Adhar Card:
Date of birth:
Male
Female
Other
Address:
Do You have a vehicle?
YES
NO
Do you Want Daily carpool?
YES
NO
Submit