To start from the beginning, for folks that might not have SSH set up at
bluehost, see: http://nevcal.com/eclectic/bluessh/bluehost-ssh.html
The cherrypy.org tutorials speak of how to configure cherrypy via
mod_python, mod_proxy, and other ways... Bluehost doesn't support those
ways, though. From their tech support, I learned that the only only
technique they support besides standard CGI is FCGI, which they mostly
support for PHP... but they say it should work for other things:
> For fcgi files to work on Bluehost you just need to make sure that
>
> 1) apache is using the right handler (AddHandler fastcgi-script .fcgi)
> 2) that the script has 755 permissions
> 3) that the script has the right shebang at the top of the file
> (/usr/bin/sh , /usr/bin/perl etc..)
To that I add: (don't use /usr/bin/env in the shebang, Apache has a
different environment than ssh)
So in .htaccess, I have the following lines:
AddHandler fcgid-script .fcgi
RewriteRule ^(errdoc.cgi(.*))$ /cgi-bin/$1 [last]
RewriteRule ^(cgi-bin/cherry.fcgi/.*)$ - [last]
# RewriteRule ^(.*$) /cgi-bin/cherry.fcgi/$1
The first corresponds to bluehost's step 1. The next is to allow my
error-document-generating script to be served by Apache, without use of
CherryPy. You could have different files here, or include any static
files you do not want served by CherryPy. Or you could be more explicit
in restricting which URLs you want to have served by CherryPy in the
subsequent lines.
The third line causes any URL that are are already explicitly invoking
cherrypy to be resolved without going through the rest of my (complex)
.htaccess. [All the complexity after these lines is already simulated in
CherryPy, in fewer lines, if I can get it to work fully.]
The final line, commented out, redirects ALL other URLs to CherryPy.
This allows the web site to work as it presently does, without the
enhancements I hope to use CherryPy for. If I can get CherryPy working,
I can uncomment this line, and the rest of the .htaccess will become
useless and can eventually be removed/archived. For testing, I simply
add cgi-bin/cherry.fcgi into the URLs I want to test.
I wanted a newer Python (2.6) so I followed the instructions at
http://eli.thegreenplace.net/2008/10/20/installing-python-25-on-bluehost/
but used a different version. I didn't package this as a single shell
script (yet).
Then I followed approximately the following instructions
http://www.tabruyn.com/site/index.php?option=com_content&view=article&id=55:tortoisesvn-subversion-and-bluehost&catid=36:digital&Itemid=58
to install SVN and flup. Not sure I actually needed this stuff.
Here is the script I reworked from that site, and updated with newer
versions, and made it easier to edit the version numbers, by abstracting
them to variables.
aprv=1.3.3
cd ~
mkdir src
cd ~/src
wget http://www.gtlib.gatech.edu/pub/apache/apr/apr-$aprv.tar.gz
tar -xzf apr-$aprv.tar.gz
cd ~/src/apr-$aprv
./configure --prefix=$HOME LDFLAGS="-L/lib64"
make
make install
apruv=1.3.4
cd ~
mkdir src
cd ~/src
wget http://www.gtlib.gatech.edu/pub/apache/apr/apr-util-$apruv.tar.gz
tar -xzf apr-util-$apruv.tar.gz
cd ~/src/apr-util-$apruv
./configure --prefix=$HOME --with-apr=$HOME LDFLAGS="-L/lib64"
make
make install
neonv=0.28.3
cd ~
mkdir src
cd ~/src
wget http://www.webdav.org/neon/neon-$neonv.tar.gz
tar -xzf neon-$neonv.tar.gz
cd ~/src/neon-$neonv
./configure --enable-shared --prefix=$HOME LDFLAGS="-L/lib64"
make
make install
svnv=1.5.4
cd ~
mkdir src
cd ~/src
wget http://subversion.tigris.org/downloads/subversion-$svnv.tar.gz
tar -xzf subversion-$svnv.tar.gz
cd ~/src/subversion-$svnv
# ./configure --prefix=$HOME --without-berkeley-db --with-zlib
--with-ssl LDFLAGS="-L/lib64"
./configure --prefix=$HOME --without-berkeley-db --with-ssl
LDFLAGS="-L/lib64"
make
make install
flupv=1.0.1
cd ~
mkdir src
cd ~/src
wget http://www.saddi.com/software/flup/dist/flup-$flupv.tar.gz
tar -xzf flup-$flupv.tar.gz
cd flup-$flupv
python setup.py install
And here is a script to install cherrypy 3.1.1, which includes cherryd,
which seems to replace the need for flup, perhaps.
chv=3.1.1
cd ~
mkdir src
cd ~/src
wget http://download.cherrypy.org/cherrypy/$chv/CherryPy-$chv.tar.gz
tar -xzf CherryPy-$chv.tar.gz
cd CherryPy-$chv
python setup.py install
# invoke cherryd as
# /home2/areliabl/src/CherryPy-3.1.1/cherrypy/cherryd -c myconfig? -d -f
-i nevcal.py
To use CherryPy with Python 2.6, one must patch it slightly (or use the
trunk), see issue #891 in the CherryPy tracker, quickly fixed by
Robert/fumanchu.
Since cherryd starts with
#! /usr/bin/env python
and that won't work when launched from Apache, either you need to use a
shell script to set up a path and then invoke cherryd, or you need to
edit cherryd and put in a hard-coded path to the python you want.
Thinking that fewer steps are faster, I opted for the latter, and first
copied cherryd to my cgi-bin as cherry.fcgi, changed the shebang line,
and ripped out the parameter parsing at the bottom (because Apache isn't
going to pass parameters either).
I replaced the parameter parsing with one line:
start( daemonize=True, fastcgi=True, imports=["mycherrysetup"])
but I haven't gotten it working yet... whether I need other parameters
or whether there is some other bug, is unknown yet.
I need a breakthrough here. I wasn't going to write all this up until I
had it all working, but this should get you as far as I have... then
maybe you will see the problem I'm having and help me... we all have
different experience in different things, of course.
--
Glenn -- http://nevcal.com/
===========================
A protocol is complete when there is nothing left to remove.
-- Stuart Cheshire, Apple Computer, regarding Zero Configuration Networking
We'd sure welcome a writeup like this at
http://tools.cherrypy.org/wiki/BluehostDeployment -- add to it as you
go.
Robert Brewer
fuma...@aminus.org
I'll give it a whirl. I've used MediaWiki a bit, but not this one.
Exactly! Some of the roads were blind alleys, but I do have a patched
CherryPy now successfully deployed at Bluehost. It is not perfect, but
it works. Perfection awaits the CherryPy 3.1.2 release.
What I am describing is a bug in CherryPy 3.1.1 that prevents it from
working it the environment that Bluehost supports. There were no Apache
issues, although if Bluehost did support other FCGI configurations,
either of them could be used successfully with CherryPy 3.1.2.
> Even before that I tried to unpack the tar.gz files for cherrypy and
> other modules i use in my python code and i got a whole bunch of
> permission denied errors. It seems you have to be root or in any case
> bluehost did not permit me to install my own packages using ssh and putty.
My latest writeup is at
http://tools.cherrypy.org/wiki/BluehostDeployment per Robert's request,
and it is trimmed a bit to what I think was actually necessary to get an
up-to-date Python/CherryPy deployed on Bluehost, rather than
_everything_ I did.
Consider what I wrote here to be a prototype of the writeup that is
there, and use it as a reference.
You are not root at Bluehost, so you cannot install stuff in the
"default" locations. If you use the preinstalled version of Python at
Bluehost, you will need to somehow convince it to install your packages
somewhere else, and I haven't figured out how to do that (too new to
Python).
What I have figured out (from various helpful web sites) is how to
install my own Python, and then installing packages using that Python
works fine. The key point to this comes in my Step 2, with the commands
cd Python-$pyv
./configure --prefix="$HOME"
This causes the install of Python to go to my Bluehost $HOME directory,
instead of to /, and I have permissions to my $HOME directory, as you
will also to yours.
> Instead they asked to provide a list of all the packages i wanted
> installed by creating a ticket and they would install them for me in
> 24 hours.
The unfortunate part about this approach is that at present, there is no
latest version of CherryPy that actually works on Bluehost. It must be
patched. So if they install the latest released version, 3.1.1, it will
not work, and you will not be able t o patch it... they will need to
patch it. Besides CherryPy, you will need flup. Beyond that, it depends
on what you need for your particularly CherryPy application that may or
may not already be installed at Bluehost.
If you install your own Python (or figure out how to install Python
packages to your own directory, I think that is possible by setting some
environment variables or something), then you can install CherryPy 3.1.1
and patch it, or wait for CherryPy 3.1.2 and install that.
> So the plan is to install all the packages including the latest
> version of cherrypy and the recommended version of python, and then i
> will start going through:
>
> 1) Documentation on deploying cherrypy on or behind or... on apache'
> 2) Your post on the fine tuning and config issues
Consider all that I have written here prior to this message to be
superseded by http://tools.cherrypy.org/wiki/BluehostDeployment and the
content of http://cherrypy.org/ticket/894
> Thanks and will post on this thread regarding any problems or
> experiences till my app is up and running on bluehost...and then you
> all will be able to see it too...
Great! Communicating our successes and failure symptoms will help to
resolve them.
> I chatted with one of the support guys over at bluehost (they have an
> online chat) so you
I have too, on occasion. Not sure if you intended to say more here --
that sentence seems unfinished. You seem to have chatted with one that
was more helpful, or at a less busy time, as none that I have talked to
have offered to install Python packages for me.
CherryPy works great with virtualenv, I do all my cherry pickin' in it.
Nice job on the write up, stuff like that is outstanding for projects
like cherrypy. There is no way that Robert and crew can do these wiki
articles, they are up to users like you and me.
regards,
Jeff
On approximately 2/19/2009 4:18 AM, came the following characters from
the keyboard of brahmaforces:
> Hi Glen:
>
> Thanks for creating this writeup and adding it to the wiki. I have
> followed it and your advice and learned a lot of things including:
>
> 1) Bluehost cannot do it for you you must do it yourself on bluehost
> 2) Install python 2.6 in your home area (instructions are available on
> the internet and in this thread before)
> 3) Install any other python modules including cherrypy, templating and
> other include modules
>
> I have done all of the above and also got flup installed.
>
> I did STEP 4 in your writeup. I created a new folder on Bluehost.
> Copied a .htaccess file in there, copied my cherrypy app/python file
> in there:
>
So to step 4 I added a new paragraph:
> The .htaccess file must be in or below the public_html directory, and
> the cgi-bin referred to must be in the public_html directory, or the
> corresponding subdirectory for the subdomain or add-on domain. I used
> .htaccess and cgi-bin in the public_html, and the paths in the
> examples reflect that.
Not sure where you created your .htaccess, but Apache on bluehost in
configured to look at public_html as the "root" path for serving URLs
for each account/domain. Subdomains and add-on domains may be at lower
levels... not sure if they allow configuring anything at higher or in
parallel to public_html, but I doubt it. Anyway, these files must be
findable by Apache according to its rules, and Bluehost's configuration,
and your configuration.
> Here is my question:
>
> 1) The Step 5 you have listed does not explain how to do what you are
> saying. Could you break step 5 down a bit. In the wiki it is listed as
> below:
>
Hmm. Not sure where you are having problems, so hardly know what to
break down, or give more detail about... I wonder if your main issue was
the one above, but if not, well, I'll answer as many of your other
issues as I can, and you can keep asking questions, and I'll keep
editing the wiki. Glad you are using it, by providing feeback, you will
make it more useful to other people... hard to know what all to write,
although I tried to be complete.
> -------------------------------------------------------------------------
> Step 5 ś
The patches are given in the tickets that I referred to in step three.
Basically, cherrypy is just a bunch of Python files, which are text
files, so you can just edit the files mention, and change them to look
like what is in the patch. I was sort of hoping that there would be a
new release of CherryPy incorporating these patches before (very many)
people would follow these instructions so didn't go into detail there,
on how to apply the patches, figuring it would be ripped out later when
the release happened. Not sure what the release schedule is for
CherryPy, as I'm still pretty new to it myself.
> 3) How do i fire up the cherrypy server on bluehost?
>
> Thanks in advance...I am almost there the last few steps are
> left...Cant wait to see my cherrypy app up on the internet....
>
It is this combination of .htaccess and cgi-bin/cherry.fcgi that starts
cherrypy via FCGI, once you get all the incantations correct for your
environment.
From your next message (and I think you were starting to see the light
about where to put things):
> Two more questions:
>
> 1) WHat is CherryD and where do i get it
>
cherryd is part of the cherrypy distribution/installation. Copy and
change. I've added the following paragraph to step 5 in the wiki:
> In the CherryPy distribution, there is a file cherryd, which
> allows/demonstrates starting and configuring a CherryPy server daemon
> (I think that is where the "d" comes from in the name) in a variety of
> environments.
> 2) Do i create a cgi-bin directory in the folder on bluehost where i
> have put my cherrypy app? Or does this go into some kind of general
> cgi-bin folder for the website in general?
>
For the main domain (and all parked domains share it), and for each
add-on domain, and for each subdomain, there is a corresponding cgi-bin
created for you by bluehost. This is the cgi-bin directory of
interest... the one that corresponds to the [sub]domain on which you
wish to run the cherrypy server. Remember that Apache is in control,
and Apache only looks in the places that bluehost configures it to look.
--
Glenn -- http://nevcal.com/
When I run my app going to thelright directory, using ssh typing python myappname.py it runs but it says
If you are running Apache on port 80, then you cannot have CherryPy also
serve on port 80. Only one app at a time can claim a port number. You
have to run CherryPy on another port number.
Which scheme are you using to run CherryPy behind Apache?
--
Tim Roberts, ti...@probo.com
Providenza & Boekelheide, Inc.
Unix/Linux means you have to be root to be able to use ports below 1024.
- Sylvain
--
Sylvain Hellegouarch
http://www.defuze.org
This occurs due to changes between Python 2.5 and 2.6. It was fixed in
CherryPy trunk in http://www.cherrypy.org/changeset/2096. Other
Python-2.6-related fixes:
* http://www.cherrypy.org/changeset/2104
* http://www.cherrypy.org/changeset/2063
Robert Brewer
fuma...@aminus.org
For those who follow: (and myself :)
Post starting issues:
Cherrypy has started, when i look in ssh via putty.
It says
serving on mydomain:2000
however when i go to http://www.mydomain:2000
it says connecting.... and nothing happens (unlike the magic that happens on my localhost)
Any ideas?
Putty DOES support cut and paste -- it just uses the X style rather than
the Windows style. As soon as you select a block of text with the
mouse, Putty immediately copies it to the clipboard. No additional
command is needed. To do paste, you just right-click in the window.
If that 'serving on...' message is spit out by CherryPy, then you
certainly do *not* want that port to be accessible to the outside world.
That is the port which CherryPy is listening on for FastCGI messages
from Apache on the same machine; it is NOT an HTTP port.
-----\ ---------\ -----------
| CP 2000 <-FastCGI-> | Apache 80 <-HTTP-> | Browser |
-----/ ---------/ -----------
Robert Brewer
fuma...@aminus.org
No. Your interface to the outside world will be Apache on port 80.
>Based on your diagram you seem to be saying that the browser will access
>cherrypy through apache on port 80. This means i should be typing;
>
>http://www.mydomain.com:80/subdirectory
>
>However when i do this i get a straight listing of files in my
>subdirectory and not the running cherrypy app. While in putty it says
>the engine is started in a normal way...
And have you configured a .htconfig file to enable FCGI for that subdirectory? Is FCGI the scheme you had planned to use?
And have you configured a .htconfig file to enable FCGI for that subdirectory? Is FCGI the scheme you had planned to use?
Correct.
> then do you think my problem could be caused by the fact that
> my files are not sitting in the root of my public_html directory
> but in a subdirectory?
No. Ideally, your cherrypy application files shouldn't be under the
Apache DocumentRoot (public_html) because of the security risk. If you
misconfigure Apache (as you seem to have done ;), then those files are
readable by the world, who may then have access to vulnerable source
code, database passwords and the like. Those files should be somewhere
else (but finding a "somewhere else" that Apache has permissions on is
not always simple). Those files should *only* be accessible via your
cgi-bin/cherryd.fcgi script.
Your htaccess says:
AddHandler fcgid-script .php
Try removing that line.
Robert Brewer
fuma...@aminus.org
My .htaccess file which sits in the public_html folder and the sub folder is as follows based on Glen's wiki entry:
# Use PHP5CGI as default
AddHandler fcgid-script .php
The above 2 lines were there from before from something else.
AddHandler fcgid-script .fcgi
RewriteRule ^(errdoc.cgi(.*))$ /cgi-bin/$1 [last]
RewriteRule ^(cgi-bin/cherryd.fcgi/.*)$ - [last]
RewriteRule ^cp/(.*)$ /cgi-bin/cherryd.fcgi/$1 [last]
RewriteRule ^(.*)$ /cgi-bin/cherryd.fcgi/$1 [last]
I even tried to move all the files to the root public_html folder and call it directly as in
http://www.maydomain.com:80/
Still got a straight list of files served by apache not the cherrypy magic, even though it is running?
By the way, where is the best place to host a cherrpy app on the internet or some good places atleast where i can run cherrypy so that it will run in an optimum way.
Trackpad makes no difference. I use those on almost all of my systems.
I was unclear in my directions. In Putty, you just select the block to
"copy". In Putty, you just right-click to "paste".
But if you want to copy from Putty to Notepad, you select the block in
Putty, switch to Notepad, then do Ctrl-V or Edit->Paste. It's just the
normal cut-and-paste scheme, except that the Putty application spells
the commands differently.
arjuna wrote:
> I googled that and found that out about putty, but it is still not
> working may be because instead of a mouse i use a touchpad (it still
> has the left and right buttons) This is because my laptop is on its
> last legs and all the USB ports are shod, so no mouse...just touchpad,
> it should work buy when i select a block and right click where i want
> to paste, nothing happens., t
Trackpad makes no difference. I use those on almost all of my systems.
I was unclear in my directions. In Putty, you just select the block to
"copy". In Putty, you just right-click to "paste".
But if you want to copy from Putty to Notepad, you select the block in
Putty, switch to Notepad, then do Ctrl-V or Edit->Paste. It's just the
normal cut-and-paste scheme, except that the Putty application spells
the commands differently.
--
You seem to be flailing around here without any real understanding of what you're trying to connect. Somehow, you need to tell Apache which requests should be routed to your CherryPy FCGI handler. I've never set up an FCGI CherryPy script, so I can't give you the recipe, but there certainly are recipes on the web. You need to UNDERSTAND those recipes, not just blindly copy config files from the web and cross your fingers to hope that they work.
>Thinking that fewer steps are faster, I opted for the latter, and first copied cherryd to >/cgi-bin/cherryd.fcgi, changed the shebang line to /home/myaccount/bin/python, and ripped >out the parameter parsing at the bottom (because Apache isn't going to pass parameters >either).
>I replaced the parameter parsing with one line:
>start( configfiles=["myconfig"], daemonize=False, fastcgi=True, imports=["mycherrysetup"])
Here i am assuming that "myconfig" is my global config file. And "mycherrypysetup" is my cherrypy app. I am trying various paths preceeding "mycherrypysetup".
The short answer is: no. You don't need Apache nor any other web server.
CherryPy can do that job just fine.
The long answer is that it depends on what you're serving. There are
places where having a frontend HTTP server makes sense. For instance
lighttpd is much faster for static content.
- Sylvain
I wasn't trying to be mean ;)
I've found in the past that using mod_rewrite was the easiest path if
you could have the CP server up as a long running process.
I've never used FCGI and I can't easily help you here.
- Sylvain
I haven't looked at how the 3.1.2 release has the above line, but I
changed it to drop the 2nd parameter. That was key in working around
some bug, I think. But I think the real fix would be different.
(Going through the 55 messages quick, and then off to bed)
> else:
> f = servers.FlupSCGIServer(application=cherrypy.tree,
> bindAddress=addr)
--
Glenn -- http://nevcal.com/
===========================
A protocol is complete when there is nothing left to remove.
-- Stuart Cheshire, Apple Computer, regarding Zero Configuration Networking
Apache starts it if needed (if it isn't already running) when you give
URL that includes http://yourdomain.com/cgi-bin/cherryd.fcgi/....
I wish. On a particular machine, port 80 can only be owned by one
process. Most hosting companies give that port to Apache, or their
preferred web server. Bluehost gives it to Apache. No one else can use
it. And they block all the other ports too. So for bluehost, must be
behind Apache, and must be FCGI
But mod_rewrite won't start your CherryPy process. FCGI will, and is
the only solution Bluehost provides that will.
The global one. The local one(s) is/are specified within the global
configuration, as far as I know, if they are needed. I'm actually not
using configuration files, but instead configuration dictionaries built
in code.
>
> question 2) What is "mycherrypysetup"
The cherrypy application code.
>
> question 3) Doing a "whereis python" on bluehost via ssh i get many
> paths to python2.6 which one should i use?/
Dunno. I installed my own, and am using it. Any python2.6 should work,
I suppose, as long as you can convince it to look at your locally
installed CherryPy packages.
> question 4) At what point do i uncomment the last line in htaccess and
> how do i test my cherrypy app
The other order. Get the app working first, then the last line gets
uncommented to expose the shorter URLs to the users.
>
> question 5) My global conf file is as follows:
>
> [global]
> server.socket_host = "localhost"
> server.socket_port = 8080
> server.thread_pool = 10
>
> # remove any limit on the request body size; cherrypy's default is
> 100MB
> # (maybe we should just increase it ?)
> server.max_request_body_size = 0
>
> # increase server socket timeout to 60s; we are more tolerant of bad
> # quality client-server connections (cherrypy's defult is 10s)
> server.socket_timeout = 60
>
>
> Do i need to change the localhost to something else on the bluehost
> server?
You don't need a sock or host when using FCGI
> Thanks in advance...A bit of friendly feedback for your wiki post.
> While everything upto point 4 is self explanatory (except how to
> install patches which you clarified in your post) Point 5 needs
> clarification along the above dimensions. (in the spirit of making
> your post even more helpful)
>
> Thanks...
Sorry for the delay. I've been busy. Seems I'm the only one that knows
anything about bluehost and cherrypy around here. I didn't mean to
become the expert, just wanted to get my application working...
Access a URL that references the FCGI file.
http://yourdomain.com/cgi-bin/cherryd.fcgi/parameters/for/your/CherryPy/application
and Apache FCGI will start the FCGI and pass it the rest of the URL.
> Also i am not clear about the subdomains
> I have a main domain and a subdomain. I have made the changes to the
> public html (htaccess and cgi bin) for the main domain. I assume this
> will mean that this will inherit down the subdomain and cherrypy will
> process the subdomain. But what of the other subdomains? Will they run
> naturally or will cherrypy try to run them?
I do subdomains differently that most cPanel users, by Parking them like
regular domains, and then tweaking my .htaccess to make them see
different things. So I know that all my subdomains will see the
.htaccess file and be affected equivalently. Not sure about the regular
subdomains.
CherryPy will only be invoked in the URL contains /cgi-bin/cherryd.fcgi/
The .htaccess rules I showed, the last one in particular (which is
commented out) adds the /cgi-bin/cherryd.fcgi/ URL fragment to all
incoming URLs that get that far (aren't handled above). So you can
tweak the rewrite rules to your heart's content, and achieve any
combination of things being handled by CherryPy or not.
If your subdomain sees the top level .htaccess and its rewrite rules,
and is affected by them, then it will try to run CherryPy. If you don't
want that tweak the rewrite rules.
If your subdomain doesn't see the top .htaccess, and you do want it
handled by CherryPy (and the regular subdomain even has its own cgi-bin
if I recall correctly), then you might have to clone and tweak the
.htaccess into the subdomain area, and possibly also the cherryd.fcgi file.
If you get the main domain working with CherryPy, these comments should
be enough to help you get the subdomains working with it, or not, as
desired.
I'm not going to start classes in mod_rewrite, though. There is lots of
documentation for that floating around. So just start from my rules,
and tweak according to the documentation and your goals.
>
> Thanks again
Can't tell from this. What URL did you send?
I think mysql runs on bluehost, but I don't use it.
This is a pure python question, better asked elsewhere, but the answer is
import warnings
warnings.simplefilter("ignore", DeprecationWarning )
> b) It starts the engine but tries to serve it on localhost:8080 (guess i
> have to tinker with my config file)
Yep.
I think this is the one that convinced me that you had it working, and
that I just needed to clean up the documentation when I had time...
FastCGI messages come in on a socket established when the FastCGI
process is launched. So there is not port involved for FastCGI, as far
as I know. Or do I misunderstand something?
If it's a TCP socket, then it has a port. If it's a Unix socket, then it
has a pseudo-file instead.
Bob
OK, well I don't know which it is, or maybe it is a pipe. I guess my
real point was that one doesn't need to configure a port when using
FastCGI... the I/O technique is already established when CherryPy
launches. So that's what I should have said.