28

I am trying to use this Python urllib2 Basic Auth Problem bit of code to download a webpage content from an URL which requires authentication. The code I am trying is:

 import urllib2, base64

request = urllib2.Request("http://api.foursquare.com/v1/user")
base64string = base64.encodestring('%s:%s' % (username, password)).replace('\n', '')
request.add_header("Authorization", "Basic %s" % base64string)   
result = urllib2.urlopen(request)

It's showing me:

./xx.py: line 1: import: command not found
./xx.py: line 3: syntax error near unexpected token `('
./xx.py: line 3: `request = urllib2.Request("http://api.foursquare.com/v1/user")'

I am wondering what I am doing wrong? I am using Python 2.7.5. How can I download file contents from an URL which requires authentication?

Community
  • 1
  • 1
user2481422
  • 738
  • 3
  • 13
  • 29
  • If import is not found then it is not related to authentication. Can you try to run python and then enter each command one by one? – philshem Mar 08 '14 at 21:36
  • to avoid the `.replace()` call, use `base64.b64encode()` instead of `encodestring()` – jfs Mar 08 '14 at 21:57
  • You either need 1.) The shebang `#!/usr/bin/env python` on the first line along with executable flag on the script file to be able to run the script with `./xx.py` OR 2.) you have to run the script with the `python xx.py` command. In the second case you don't need the shebang and the executable flag. – pasztorpisti Mar 08 '14 at 22:05
  • 1
    @pasztorpisti ...that said, if the goal is to define a command, the shebang and +x flag are the Right Approach (and the script probably shouldn't have a `.py` extension at all; see https://www.talisman.org/~erlkonig/documents/commandname-extensions-considered-harmful for more discussion on that point). – Charles Duffy Mar 08 '14 at 22:07
  • @CharlesDuffy Sure, the `.py` extension on linux isn't needed. This is basically true for all interpreted script files that have shebang + exec flag. – pasztorpisti Mar 08 '14 at 22:10
  • 1
    @pasztorpisti ...not just not needed, but actively harmful, as it means you can't reimplement in a different language without either needing to modify all callers or keeping it there with a now-misleading extension. And also, as we put it to people in #bash, "do you run `ls.elf`?" – Charles Duffy Mar 08 '14 at 22:12
  • @CharlesDuffy Good point. You can still reimplement it in a different language - it just looks ridiculous to have a bash script in a file with `.py` extension and its confusing at the same time. :-) – pasztorpisti Mar 08 '14 at 22:17
  • @CharlesDuffy: *Installed* scripts (that are in PATH) do not need the file extension on Unix. Otherwise `.py` extension may be useful e.g., to import the file as a Python module. – jfs Mar 08 '14 at 22:33
  • @J.F.Sebastian, indeed so. However, if you're building something which is intended to be both a library and a command, best practice in the Python world is to develop and install it as a library and have setuptools build an extensionless (or, on Windows, `.exe`) wrapper for you. – Charles Duffy Mar 08 '14 at 22:49
  • @CharlesDuffy: yes. It is what setuptools' entry_points option does by default. – jfs Mar 08 '14 at 22:52
  • ...we're in rather violent agreement here, aren't we? :) – Charles Duffy Mar 08 '14 at 23:09

6 Answers6

59

It's not an issue related to authentication at the first step. Your import is not working. So, try writing this on first line:

#!/usr/bin/python

and for the time being run using

python xx.py

For you here is one explanation:

>>> abc = "Hei Buddy"
>>> print "%s" %abc
Hei Buddy
>>> 

>>> print "%s" %xyz

Traceback (most recent call last):
  File "<pyshell#6>", line 1, in <module>
    print "%s" %xyz
NameError: name 'xyz' is not defined

At first, I initialized abc variable and it works fine. On the otherhand, xyz doesn't work as it is not initialized!

anon582847382
  • 17,467
  • 4
  • 45
  • 53
Sharif Mamun
  • 3,240
  • 5
  • 26
  • 49
  • When I runned my script with your command then it shows: `base64string = base64.encodestring('%s:%s' % (abc, xyz)).replace('\n', '') NameError: name 'abc' is not defined` – user2481422 Mar 08 '14 at 21:42
  • You are replacing %s with a variable called abc, so you need to initialize that first! – Sharif Mamun Mar 08 '14 at 21:44
  • Because `abc` is probably not instantiated. Don't get ahead of yourself. Instantiate your variables ahead of using them. – NullDev Mar 08 '14 at 21:44
  • I added one example in my answer. Have a look into that! – Sharif Mamun Mar 08 '14 at 21:45
  • If the answer solves your problem, upvote and accept the answer! Cheers! – Sharif Mamun Mar 08 '14 at 21:51
  • 1
    It's not necessary to **both** add the shebang and explicitly invoke an interpreter. As such, I'm not sure this really constitutes good advice. – Charles Duffy Mar 08 '14 at 22:03
  • 1
    Also, the discussion of the unrelated variable initialization issues distract from the on-topic response to the actual question. Better to ask the questioner to file a separate Q than to make something that's less useful to other people. – Charles Duffy Mar 08 '14 at 22:06
  • [you do not need shebang if you run it as `python xx.py`](http://stackoverflow.com/a/22275721/4279) – jfs Mar 08 '14 at 22:14
  • @J.F.Sebastian, that's true, but phrasing it the way you do here implies that it's better to explicitly pass the interpreter and not use a shebang. That's generally contrary to accepted best practices. – Charles Duffy Mar 08 '14 at 22:15
  • On my Windows machine I had to add `#!/usr/bin/env python` instead of `#!/usr/bin/python` – Eerik Sven Puudist Oct 02 '18 at 10:44
9

Are you using a UNIX based OS such as Linux? If so, add a shebang line to the very top of your script:

#!/usr/bin/python

Underneath which you would have the rest of the code (xx.py in your case) that you already have. Then run that same command at the terminal:

$ python xx.py

This should then work fine, as it is now interpreting this as Python code. However when running from the terminal this does not matter as python tells how to interpret it here. What it does allow you to do is execute it outside the terminal, i.e. executing it from a file browser.

Community
  • 1
  • 1
anon582847382
  • 17,467
  • 4
  • 45
  • 53
  • I know, that's obvious. I was just making the question more applicable to new users that may stumble across this post with the same problem, thank you. That way, when they read my post they know that if they are using UNIX it will be applicable to them. – anon582847382 Mar 08 '14 at 21:42
  • When I runned my script with your command then it shows: `base64string = base64.encodestring('%s:%s' % (abc, xyz)).replace('\n', '') NameError: name 'abc' is not defined` – user2481422 Mar 08 '14 at 21:43
  • @user2481422 That cannot be, as the line that it is saying is incorrect is not in the code that you have posted. Post the full code. But anyway, Python is saying that it cannot find a variable named `abc`. Try declaring it first with `abc = 'some_value'`. But this is a separate issue, so I won't discuss it here. If the problem persists, ask a different question. The issue that you have posted in the question is solved with my answer. – anon582847382 Mar 08 '14 at 21:45
  • [you do not need the shebang if you run it as `python xx.py`](http://stackoverflow.com/a/22275721/4279) – jfs Mar 08 '14 at 22:12
  • @J.F.Sebastian, indeed, but it's better to use the shebang and **not** use the explicit interpreter -- that way you're delegating the choice of interpreter to the program's author, who knows better than anyone else what the right interpreter for that program is. – Charles Duffy Mar 08 '14 at 22:14
  • @CharlesDuffy: the point is that *even if there is no shebang* the script runs if you use `python xx.py` (`python` even accepts an empty file here). – jfs Mar 08 '14 at 22:19
  • @J.F.Sebastian, absolutely true, but not a truth we should be encouraging newbies to take account or advantage of in their work. – Charles Duffy Mar 08 '14 at 22:51
7

When you see "import: command not found" on the very first import, it is caused by the parser not using the character encoding matching your py file. Especially when you are not using ASCII encoding in your py file.

The way to get it right is to specify the correct encoding on top of your py file to match your file character encoding.

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import os
Li Li
  • 197
  • 3
  • 5
  • this should be helpful since utf-8 is the most popular encoding nowadays, even on Python source code – Huifang Feng Oct 27 '17 at 18:24
  • The answer is wrong. The error message is from the shell -- no python interpreter is running in this case. [My answer explains why](https://stackoverflow.com/a/22275721/4279) – jfs Jul 02 '20 at 18:49
4

If you run a script directly e.g., ./xx.py and your script has no shebang such as #!/usr/bin/env python at the very top then your shell may execute it as a shell script. POSIX says:

If the execl() function fails due to an error equivalent to the [ENOEXEC] error defined in the System Interfaces volume of POSIX.1-2008, the shell shall execute a command equivalent to having a shell invoked with the pathname resulting from the search as its first operand, with any remaining arguments passed to the new shell, except that the value of "$0" in the new shell may be set to the command name. If the executable file is not a text file, the shell may bypass this command execution. In this case, it shall write an error message, and shall return an exit status of 126.

Note: you may get ENOEXEC if your text file has no shebang.

Without the shebang, you shell tries to run your Python script as a shell script that leads to the error: import: command not found.

Also, if you run your script as python xx.py then you do not need the shebang. You don't even need it to be executable (+x). Your script is interpreted by python in this case.

On Windows, shebang is not used unless pylauncher is installed. It is included in Python 3.3+.

jfs
  • 346,887
  • 152
  • 868
  • 1,518
2

I've experienced the same problem and now I just found my solution to this issue.

#!/usr/bin/python

import sys
import os

os.system('meld "%s" "%s"' % (sys.argv[2], sys.argv[5]))

This is the code[1] for my case. When I tried this script I received error message like :

import: command not found

I found people talks about the shebang. As you see there is the shebang in my python code above. I tried these and those trials but didn't find a good solution.

I finally tried to type the shebang my self.

#!/usr/bin/python

and removed the copied one.

And my problem solved!!!

I copied the code from the internet[1].

And I guess there had been some unseeable(?) unseen special characters in the original copied shebang statement.

I use vim, sometimes I experience similar problems.. Especially when I copied some code snippet from the internet this kind of problems happen.. Web pages have some virus special characters!! I doubt. :-)

Journeyer

PS) I copied the code in Windows 7 - host OS - into the Windows clipboard and pasted it into my vim in Ubuntu - guest OS. VM is Oracle Virtual Machine.

[1] http://nathanhoad.net/how-to-meld-for-git-diffs-in-ubuntu-hardy

Jeonghum
  • 957
  • 3
  • 9
  • 24
1

It's about Shebang

#!usr/bin/python

This will tell which interpreter to wake up to run the code written in file.

SJ26
  • 31
  • 7