I can't serve my own favicon

326 views
Skip to first unread message

Bao Niu

unread,
Apr 29, 2014, 2:32:05 PM4/29/14
to cherryp...@googlegroups.com
I am trying the new tutorials. However I found my custom favicon doesn't show up as expected. I've examined my code and configuration file carefully but didn't find anything wrong. Here is my code and configuration file:

code:

import os.path
import random
import string

import cherrypy


class StringGenerator(object):
    @cherrypy.expose
    def index(self):
        return """<html>
          <head>
            <link href="/static/css/style.css" rel="stylesheet">
          </head>
      <body>
        <form method="get" action="generate">
          <input type="text" value="8" name="length" />
              <button type="submit">Give it now!</button>
        </form>
      </body>
    </html>"""

    @cherrypy.expose
    def generate(self, length=8):
        some_string = ''.join(random.sample(string.hexdigits, int(length)))
        cherrypy.session['mystring'] = some_string
        return some_string

    @cherrypy.expose
    def display(self):
        return cherrypy.session['mystring']

if __name__ == '__main__':
    cherrypy.config.update("cherrypy_config")
    cherrypy.quickstart(StringGenerator(), '/', "cherrypy_config")

configuration file, under the same directory of the code:
[/]
tools.sessions.on = True
tools.staticdir.on = True
tools.staticdir.root = os.path.abspath(os.getcwd())
tools.staticdir.dir = ""

[/static]
tools.staticdir.on = True
tools.staticdir.dir = "./public"

[/favicon.ico]
tools.staticfile.on = True
tools.staticfile.filename = os.path.join(os.getcwd(), "public/favicon.ico")

The directories of "public" is properly created so I can use static css file. Just the favicon doesn't show up. Could someone take a look at my code and configuration file to see if there is anything I'm missing? Thanks.

Tim

unread,
Apr 29, 2014, 4:41:30 PM4/29/14
to cherryp...@googlegroups.com
Do os.path.abspath(os.getcwd()) and os.path.join(os.getcwd(), "public/favicon.ico") give you the same path? Have you tried replacing them with string literals for debugging purposes. I personally feel more comfortable with dictionary based configuration because I know the syntax from using python in general but if the code you have has the correct paths it should work. Also have you tried this in more than one brand of browser and cleared the browser cache.

Tim

unread,
Apr 29, 2014, 4:45:30 PM4/29/14
to cherryp...@googlegroups.com
Also I am not sure on this do you have access to the os module in configuration files? How would it be included? I see cherrypy attribute in the online examples but I don't know about the os module.

On Tuesday, April 29, 2014 1:32:05 PM UTC-5, Bao Niu wrote:

Bao Niu

unread,
Apr 29, 2014, 5:11:59 PM4/29/14
to cherryp...@googlegroups.com
Hi Tim,

Thanks for your reply. I just tried replacing os.getcwd() stuff with string literal, not helping. It must be something other than this because css file can be located by cherrypy. The problem seems to be local to favicon configuration.

By the way, I'm using google chrome. I also used incognito mode to rule out any cache problems.

Given that, favicon still not showing. Need some help.
Message has been deleted

Tim

unread,
Apr 30, 2014, 1:40:45 AM4/30/14
to cherryp...@googlegroups.com
configuration = {
'global':{
'server.socket_host': '127.0.0.1',
'server.socket_port': 30114,
'tools.sessions.on': True,
'tools.sessions.timeout': 1440,
'server.thread_pool': 10,
'server.thread_pool_max': -1
},
'/':{
'tools.secureheaders.on': False,
'tools.staticdir.root': "C:/Users/tim/Projects/dms2alpha0.1/front_end"
},
'/js': {
'tools.staticdir.on':True,
'tools.staticdir.dir': "js"
},
'/css':{
'tools.staticdir.on':True,
'tools.staticdir.dir': "css"
},
'/img':{
'tools.staticdir.on':True,
'tools.staticdir.dir': "img"
},
'/jtable':{
'tools.staticdir.on':True,
'tools.staticdir.dir': "jtable"
},
'/bootstrap':{
'tools.staticdir.on':True,
'tools.staticdir.dir': "bootstrap"
},
'/favicon.ico':{
'tools.staticfile.on':True,
'tools.staticfile.filename': "C:/Users/tim/Projects/dms2alpha0.1/front_end/favicon.ico"
}
}
Well it may not be ideal but that is the configuration I am using and my favicon is working. Hope it of some help.

Bao Niu

unread,
Apr 30, 2014, 2:04:33 AM4/30/14
to cherryp...@googlegroups.com
Hi Tim,

Thanks for your codes here. I've noticed one thing here though, isn't favicon considered part of the server configuration as opposed to application configuration? So that's why I used cherrypy.config.update() in my codes. Am I missing something?

By the way, have you tried using Chrome? It seems to me that my Firefox works but not Chrome. Could this be a bug?

Tim

unread,
Apr 30, 2014, 2:24:02 AM4/30/14
to cherryp...@googlegroups.com
As far as the configuration goes, I am only running one application with the server instance. The favicon.ico is showing in chrome and firefox for me.

Bao Niu

unread,
Apr 30, 2014, 3:38:31 AM4/30/14
to cherryp...@googlegroups.com

This is kind of weird, I've double checked my code and it still not working. I don't see much difference between my configuration and yours. Could it be the reason that I'm using a config file instead of a config dictionary? But they should be functionally equivalent.
Could someone take a look at my codes above? Thanks.

Eric Larson

unread,
Apr 30, 2014, 9:58:39 AM4/30/14
to cherryp...@googlegroups.com
Bao Niu <niub...@gmail.com> writes:

> This is kind of weird, I've double checked my code and it still not
> working. I don't see much difference between my configuration and yours.
> Could it be the reason that I'm using a config file instead of a config
> dictionary? But they should be functionally equivalent.
> Could someone take a look at my codes above? Thanks.

I'd consider trying to make the config work in a normal dictionary
rather than the config file to see what the problem is. I have no doubt
there is a mismatch somewhere that isn't showing its head and using
dictionary directly will help reveal the issue (or even a bug!).

With that in mind, I've found that it is easier to use the dictionary
method of config than the config file. I still have config information
provided to the application, but it gets parsed and created and then
applied as necessary to the cherrypy dictionary config. A simple
example is accepting a PORT value. That can be applied in most of my
apps via enviroment variable, command line flag, or config file entry.

So, give the dictionary methodology a try and see how that works out. It
is a great way to use cherrypy and is very common. If that is working
well, then try the config file approach if that is what you need /
want. Understanding the dictionary configuration first should make
debugging the config much easier.

Best of luck!

Eric

Bao Niu

unread,
Apr 30, 2014, 3:13:58 PM4/30/14
to cherryp...@googlegroups.com
Here is my new codes, with config file being replaced by config dictionary, and using string literal to specify url.
    favconfig = {"/favicon.ico": {
                    "tools.staticfile.on": True,
                    "tools.staticfile.filename": "/home/springfest/Desktop/public/favicon.ico"
                }
            }
    cherrypy.config.update(favconfig)
    cherrypy.quickstart(StringGenerator(), '/', "")
My favicon still now showing, only that default cherry shows up. This time neither Firefox nor Chrome would work. Seems to be a backward step:(
Could someone please copy and paste my above codes and give it a test? Thanks.

Sylvain Hellegouarch

unread,
Apr 30, 2014, 3:22:24 PM4/30/14
to cherryp...@googlegroups.com
Bao,

Make sure the request reaches the server (you should see a line to /favicon.ico in the logs). Browsers tend to cache it and don't always make the request for it.


--
You received this message because you are subscribed to the Google Groups "cherrypy-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cherrypy-user...@googlegroups.com.
To post to this group, send email to cherryp...@googlegroups.com.
Visit this group at http://groups.google.com/group/cherrypy-users.
For more options, visit https://groups.google.com/d/optout.



--
- Sylvain
http://www.defuze.org
http://twitter.com/lawouach

Sylvain Hellegouarch

unread,
Apr 30, 2014, 3:23:11 PM4/30/14
to cherryp...@googlegroups.com
Ah and also, the config for an application must be passed to the quickstart call, not the config.update.

 cherrypy.quickstart(StringGenerator(), '/', favconfig)

Bao Niu

unread,
Apr 30, 2014, 3:55:19 PM4/30/14
to cherryp...@googlegroups.com
Thank you so much Sylvain! I have a feeling that it is where the problem is, i.e. it never reach the server!

I've searched the terminal and there is no line mentioning "/favicon.ico" in the logs. How can I make sure it reaches the server? I've used  both config.update and quikstart specifying config dictionary. Isn't it enough?
Here is my edited latest version:

    cherrypy.quickstart(StringGenerator(), '/', favconfig)

Joel Rivera

unread,
Apr 30, 2014, 4:37:31 PM4/30/14
to cherryp...@googlegroups.com
You are probably seeing a cached value of a favicon, usually it
cached by the browser. Get the url directly to the favicon:

host/favicon.ico

make a "hard refresh" Ctrl+F5 that will bypass the cache on the browser
or just delete the cache of the browser.
> > <s...@defuze.org<javascript:>
> > > wrote:
> >
> >> Bao,
> >>
> >> Make sure the request reaches the server (you should see a line to
> >> /favicon.ico in the logs). Browsers tend to cache it and don't
> >> always make the request for it.
> >>
> >>
> >> On 30 April 2014 21:13, Bao Niu <niub...@gmail.com <javascript:>>
> >>> send an email to cherrypy-user...@googlegroups.com <javascript:>.
> >>> To post to this group, send email to
> >>> cherryp...@googlegroups.com<javascript:> .
> >>> Visit this group at http://groups.google.com/group/cherrypy-users.
> >>> For more options, visit https://groups.google.com/d/optout.
> >>>
> >>
> >>
> >>
> >> --
> >> - Sylvain
> >> http://www.defuze.org
> >> http://twitter.com/lawouach
> >>
> >
> >
> >
> > --
> > - Sylvain
> > http://www.defuze.org
> > http://twitter.com/lawouach
> >
>



--
Rivera²

Bao Niu

unread,
Apr 30, 2014, 4:40:58 PM4/30/14
to cherryp...@googlegroups.com
Hi Joel,
 
I've tried Ctrl+F5, it doesn't help. By the way I've been using Chrome's incognito or Firefox's Private browsing, those by default does not cache. Could there be any other reason that it doesn't reach the server?
This small problem really gives me a headache now:)

Bao Niu

unread,
May 2, 2014, 12:29:27 AM5/2/14
to cherryp...@googlegroups.com
Could some one please help take a look at my codes? Really want to find out what's wrong with it. Have tried many times and still got nowhere...

Joel Rivera

unread,
May 2, 2014, 2:42:50 AM5/2/14
to cherryp...@googlegroups.com
For what I can see the problem is most likely outside cherrypy, if you
were having a 404 or 500 or some other response then it would be easier
to give you a better answer, are you sure that you are point to the
right port?

http://localhost:8080/favicon.ico

right?

In the html you're referring "/static/css/style.css" and not
setting /static. Why is that? a half snipped or are you reaching
another http server?

Can you explain in more detail *exactly* what urls are you expecting to
be available and put the respective code that should support those?




On Thu, 1 May 2014 21:29:27 -0700 (PDT)
--
Rivera²

Lorenzo Bolla

unread,
May 2, 2014, 3:55:14 AM5/2/14
to cherryp...@googlegroups.com
Hi Bao,

This works for me:

Note that I had to specify the content type of the favicon.ico, and that I passed the config object as an argument of quickstart().
Try to run it and visit: http://localhost:8080/favicon.ico
You'll get your favicon. As others has said, browsers cache such things, so you may need to clear your cache or do the usual "deep refresh" in your browser.

hth,
L.


To unsubscribe from this group and stop receiving emails from it, send an email to cherrypy-user...@googlegroups.com.
To post to this group, send email to cherryp...@googlegroups.com.

Bao Niu

unread,
May 2, 2014, 4:21:50 AM5/2/14
to cherryp...@googlegroups.com

Thank you very much Joel.
I'm sure that in my code it points to the right url and port. I double checked this by putting
http://localhost:8080/favicon.ico
directly to the address bar and it can locate my desired favicon without any problem.
However it just doesn't show up as favicon, the default little cherry icon keeps persisting all along.

The reason for referring  "/static/css/style.css" and not "/static" is that my codes is actually derived from the new tutorial here:
http://cherrypydocrework.readthedocs.org/tutorials.html#tutorial-6-what-about-my-javascripts-css-and-images

One thing that is particularly abnormal is that "favicon" doesn't show in log at all, which could mean that the server doesn't even attempt to locate my specified url for favicon??? If this is the case then the problem is still in Cherrypy, I'm afraid.
If Ctrl+F5 doesn't work, neither does Private browsing nor incognito, how can I *force* the server to read from specified url and not from the default /faviocon? In addition, what is the rationale of using both cherrypy.config.update and quickstart config to point to the same configuration dictionary??

My current codes is as below.
            "/": {
                "tools.sessions.on": True,
                "tools.staticdir.on": True,
                "tools.staticdir.root": os.path.abspath(os.getcwd()),
                "tools.staticdir.dir": ""
                },
            "/static": {
                "tools.staticdir.on": True,
                "tools.staticdir.dir": "./public"
                },

            "/favicon.ico": {
                    "tools.staticfile.on": True,
                    "tools.staticfile.filename": "/home/springfest/Desktop/public/favicon.ico"
                }
            }
    cherrypy.config.update(favconfig)
    cherrypy.quickstart(StringGenerator(), '/', favconfig)

Bao Niu

unread,
May 2, 2014, 5:02:57 AM5/2/14
to cherryp...@googlegroups.com
UPDATE:

It seems to be the browser's problem, I just tried completely clear browsing history including cookies and images and it works.

However, I still am curious about two questions:
#1. How come the favicon.ico doesn't show up in log, something like: " /favicon.ico  200 "? Does the server just *silently* locate it?
#2. why do I have to use both cherrypy.config.update method to update favicon configuration, and at the same time using quickstart config parameter to do the same thing again? Is favicon considered both global server configuration AND application configuration??

Thanks.

Eric Larson

unread,
May 2, 2014, 12:13:48 PM5/2/14
to cherryp...@googlegroups.com

One thing to be aware of is that quickstart can clobber a config you
already updated via cherrypy.config.update.

For example:

# Update our config
cherrypy.config.update({'/: {'tools.my_tool.on': True}}),

# Start our app with quickstart but clobber our config! Ooops!
cherrypy.quickstart(MyApp(), '/', {'tools.my_other_tool.on': True})

Here is why:

>>> foo = {'/': {'bar': True}}
>>> foo.update({'/': {'baz': True}})
>>> print(foo)
{'/': {'baz': True}}

You've set the key name in the root of the config, therefore, the entire
child node is replaced. It doesn't do a depth first, recursive update.

One great thing about cherrypy is the ability to mount different apps
along with different configs. If you're using quickstart, it can be easy
to screw this up. I typically do one of two things:

1. If it is a single app then prepare the entire config and only pass
it quickstart.
2. If I have multiple apps I'm mounting then update the config via
cherrypy.config.update and manually do the start process defined in
quickstart.

Here is a condensed version of what quickstart does (comments removed
and names changed for clarity):

def quickstart(root=None, script_name="", config=None):
if config:
cherrypy.config.update(config)

tree.mount(root, script_name, config)

engine.signals.subscribe()
engine.start()
engine.block()

When I have multiple apps, I'll typically mount them at different points
in the application setup, then I'll start the server with:

engine.signals.subscribe()
engine.start()
engine.block()

What this does is:

1. setup signal handling so things like Control-C or SIGTERM (kill pid)
works as expected.
2. Starts the engine which starts listening on the host port
3. Start blocking and waiting for connections

I found that understanding this aspect of cherrypy makes many
configuration questions much easier to debug when it seems like things
should work. It also exposes the fact that cherrypy is *extremely*
unopinionated! You can use whatever means you'd like to construct your
config and apply it to your server. This can be helpful because
complicated systems that may allow registering endpoints via setuptools
entry points can be done using normal Python functions.

But for the vast majority of folks, just making sure you pass in your
config once via quickstart is just fine and a great way to use
cherrypy.

Hope that explanation helps a bit. If you get confused again, I highly
recommend taking a look at the source. CherryPy is not clever when it
comes to code, which makes it an excellent source of information when
the docs feel lacking.

Obviously, we are working on improving the docs as well, but even with
great docs, having the source to read is an excellent option.

Best of luck!

Eric


P.S. I've had to use this "read the source" technique many times in
other projects such as Django, which has excellent docs. It is not a
failing of Django as much as it is a fantastic skill to learn when using
open source software!
--
Sent with my mu4e

Bao Niu

unread,
May 2, 2014, 6:26:18 PM5/2/14
to cherryp...@googlegroups.com
Thanks guys for this hand-holding approach. I appreciate it. By the way, the new docs by no means feel lacking, they are EXCELLENT!



--
You received this message because you are subscribed to a topic in the Google Groups "cherrypy-users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/cherrypy-users/IQ_mz1OHmtU/unsubscribe.
To unsubscribe from this group and all its topics, send an email to cherrypy-user...@googlegroups.com.
To post to this group, send email to cherryp...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages