python- split() doesn't work inside __init__ -


i writing code serve html file using wsgi.when write straight forward function no error :

from wsgiref.simple_server import make_server import os    ...    ... def app(environ, start_response):     path_info = environ["path_info"]     resource = path_info.split("/")[1] #i no error here split works totally fine. 

now when try put code inside class error nonetype has no attribute split. perhaps environ inside __init__ doesn't initialised , that's why split returns nothing. following file in class candy resides :

import os class candy:     def __init__(self):             #self.environ = environ             #self.start = start_response             self.status = "200 ok"             self.headers = []      def __call__(self , environ , start_response):         self.environ = environ         self.start = start_response      #headers = []     def content_type(path):         if path.endswith(".css"):             return "text/css"         else:             return "text/html"       def app(self):         path_info = self.environ["path_info"]         resource = path_info.split("/")[1]          #headers = []         self.headers.append(("content-type", content_type(resource)))          if not resource:             resource = "login.html"         resp_file = os.path.join("static", resource)          try:             open(resp_file, "r") f:                 resp_file = f.read()         except exception:             self.start("404 not found", self.headers)             return ["404 not found"]          self.start("200 0k", self.headers)         return [resp_file] 

following server.py file invoke make_server :

from wsgiref.simple_server import make_server candy import candy #from app import candy_request  candy_class = candy()  httpd = make_server('localhost', 8000, candy_class.app) print "serving http on port 8000..."  # respond requests until process killed httpd.serve_forever()  # alternative: serve 1 request, exit #httpd.handle_request() 

any ? how error sorted , right in assumption?

to explain you're doing wrong here, let's start simple concepts - wsgi application is.

wsgi application callable receives request environment, , callback function starts response (sends status line , headers user). then, callable must return 1 or more strings, constitute response body.

in simplest form, have working it's just

def app(environ, start_response):     start_response("200 ok", [("content-type", "text/plain")])     return "hello, world"  make_server('localhost', 8000, app).serve_forever() 

whenever request comes, app function gets called, starts response , returns string (or return iterable of multiple strings, e.g. ["hello, ", "world"])

now, if want class, works this:

 class myapp(object):      def __init__(self):          pass       def __call__(self, environ, start_response):          start_response("200 ok", [("content-type", "text/plain")])          return "something"   app = myapp()  make_server("localhost", 8000, app).serve_forever() 

in case, callable app, , it's __call__ method of caddy class instance.

when request comes, app.__call__ gets called (__call__ magic method turns class instance in callable), , otherwise works same app function first example. except have class instance (with self), can pre-configuration in __init__ method. without doing in __init__ it's useless. e.g., more realistic example this:

 class myapp(object):      def __init__(self):          self.favorite_color = "blue"       def __call__(self, environ, start_response):          start_response("200 ok", [("content-type", "text/plain")])          return "my favorite color {}".format(self.favorite_color)  ... 

then, there's thing. want streaming response, generated on time. maybe it's big, or maybe takes while. that's why wsgi applications can return iterable, rather string.

def app(environ, start_response):     start_response("200 ok", [("content-type", "text/plain")]))     yield "this triumph\n"     time.sleep(1)     yield "i'm making note here\n"     time.sleep(1)     yield "huge success\n"  make_server("localhost", 8000, app).serve_forever() 

this function returns generator returns text, piece piece. although browser may not show this, try running curl http://localhost:8000/.

now, same classes be:

class myapp(object):     def __init__(self, environ, start_response):         self.environ = environ         self.start = start_response      def __iter__(self):         self.start("200 ok", [("content-type", "text/plain")]))         yield "this triumph\n"         time.sleep(1)         yield "i'm making note here\n"         time.sleep(1)         yield "huge success\n"  make_server("localhost", 8000, myapp).serve_forever() 

here, pass myapp (the class) application callable - is. when request comes gets called, it's had written myapp(environ, start_response) somewhere, __init__ starts , creates instance specific request. then, instance iterated, __iter__ starts produce response. after it's done, instance discarded.

basically, that's it. classes here convenience closures hold data. if don't need them, don't use classes, use plain functions - flat better nested.


now, code.

what code uses callable candy().app. doesn't work because doesn't made receive environ , start_response passed. should fail 500 error, saying app() takes 1 positional arguments 3 given.

i assume code in question modified after got nonetype has no attribute split issue, , had passed __init__ when creating candy_instance = candy() when __init__ still had 2 arguments (3 self). not sure - should've failed earlier.

basically, passed wrong objects make_server , class mix of 2 different ideas.

i suggest check examples above (and read pep-333), decide need, , structure candy class that.

  • if need return on every request, , don't have persistent state - don't need class @ all.

  • if need persistent state (config, or, maybe, database connection) - use class instance, __call__ method, , make __call__ return response.

  • if need respond in chunks, use either generator function, or class __iter__ method. or class __call__ yields (just function).

hope helps.


Comments

Popular posts from this blog

ubuntu - PHP script to find files of certain extensions in a directory, returns populated array when run in browser, but empty array when run from terminal -

php - How can i create a user dashboard -

javascript - How to detect toggling of the fullscreen-toolbar in jQuery Mobile? -