I have added sendgrid to my django app
Followed the simple steps from here https://github.com/elbuo8/sendgrid-django
generated acount and and copied the api at sengrid site
Added code to my view
sg = sendgrid.SendGridAPIClient(apikey=os.environ.get('SENDGRID_API_KEY'))
from_email = Email("commerce#gmail.com")
to_email = Email("lopa#gmail.com")
subject = "Sending with SendGrid is Fun"
content = Content("text/plain", "and easy to do anywhere, even with Python")
mail = Mail(from_email, subject, to_email, content)
response = sg.client.mail.send.post(request_body=mail.get())
messages.add_message(request, messages.SUCCESS, str(payment.id) + response.status_code + response.body + response.headers)
And getting Error
HTTP Error 401: Unauthorized
What could be the problem?
> Traceback Traceback: File
> "C:\Users\PAPA\DEV\rent_unit\rent_unit_venv\lib\site-packages\django\core\handlers\base.py"
> in get_response
> 132. response = wrapped_callback(request, *callback_args, **callback_kwargs) File "C:\Users\PAPA\DEV\rent_unit\rent_unit_venv\lib\site-packages\django\contrib\auth\decorators.py"
> in _wrapped_view
> 22. return view_func(request, *args, **kwargs) File "C:\Users\PAPA\DEV\rent_unit\src\payment\views.py" in payment_new
> 251. response = sg.client.mail.send.post(request_body=mail.get()) File
> "C:\Users\PAPA\DEV\rent_unit\rent_unit_venv\lib\site-packages\python_http_client\client.py"
> in http_request
> 204. return Response(self._make_request(opener, request)) File
> "C:\Users\PAPA\DEV\rent_unit\rent_unit_venv\lib\site-packages\python_http_client\client.py"
> in _make_request
> 138. return opener.open(request) File "c:\python27\Lib\urllib2.py" in open
> 435. response = meth(req, response) File "c:\python27\Lib\urllib2.py" in http_response
> 548. 'http', request, response, code, msg, hdrs) File "c:\python27\Lib\urllib2.py" in error
> 473. return self._call_chain(*args) File "c:\python27\Lib\urllib2.py" in _call_chain
> 407. result = func(*args) File "c:\python27\Lib\urllib2.py" in http_error_default
> 556. raise HTTPError(req.get_full_url(), code, msg, hdrs, fp)
>
> Exception Type: HTTPError at
> /payment/new/28/http://127.0.0.1:8000/lease/payment_details/28/
> Exception Value: HTTP Error 401: Unauthorized
The problem is exactly what it says; You're not authorized. Most likely you're API key isn't set.
The instructions you added to your question show the SENDGRID_API_KEY being added to the Django settings.py, while you're code shows you fetching from an environment variable.
Environment Variable Approach
If you're using the environment variable approach, make sure you've set an environment variable called SENDGRID_API_KEY. You can check it it's set by opening a python console and typing:
import os
os.environ.get('SENDGRID_API_KEY')
If a key isn't printed out, that means it's missing. Each OS has a different way of setting environment variables permanently, so I'm not going to list them all out here.
Settings.py Approach
If you're going with the Django settings.py approach, simply replace:
sg = sendgrid.SendGridAPIClient(apikey=os.environ.get('SENDGRID_API_KEY'))
with
from django.conf import settings
sg = sendgrid.SendGridAPIClient(apikey=settings.SENDGRID_API_KEY)
Environment Variable in Settings.py Approach
Finally, since settings.py is an executable python file, you can also perform an environment variable import there. This has the benefit of being adjustable from a system level or a Heroku console, but still uses settings.py.
# inside settings.py
import os
SENDGRID_API_KEY = os.environ.get('SENDGRID_API_KEY')
Just update your code to use the one you want if you prefer not to use environment variable or settings
SENDGRID_API_KEY = '*sendgrid***api*'
sg = sendgrid.SendGridAPIClient(apikey=SENDGRID_API_KEY )
I have faced same error, I use this cli to solve: e.g(my_api_key)
set SENDGRID_API_KEY=SG.FHWXmV68Td2cEYJQrPjDdQ.I1VEkE2CBg7--r7QfS-AzhfSU5
( !!! do not use ' ' like : 'SG.FHWXmV68Td2cEYJQrPjDdQ.I1VEkE2CBg7--r7QfS-AzhfSU5' ).
also.
Do not replace SENDGRID_API_KEY line with your API_KEY :
sg =SendGridAPIClient(os.environ.get('SENDGRID_API_KEY'))
. And you should refer this document :
https://github.com/sendgrid/sendgrid-python
I think this problem is because the window user,see this and you will understand . Acc to this doc :
Related
Although the official algosdk (Python SDK for Algorand) documentation suggests that a wallet can be recovered by simply invoking the following function (link):
create_wallet(name, pswd, driver_name='sqlite', master_deriv_key=None)
with the fourth argument:
master_deriv_key (str, optional) – if recovering a wallet, include
wallet recovery does not work in my code and leads to experience an exception as well. Also the official Algorand documentation shows how to use the abovementioned function for recovering a wallet (link):
# recover the wallet by passing mdk when creating a wallet
new_wallet = kcl.create_wallet("MyTestWallet2", "testpassword", master_deriv_key=mdk)
Below, you can watch at my code, a very simple snippet that I coded to make some tests with Algorand SDK:
from algosdk import kmd
from algosdk import mnemonic
kmd_clt = kmd.KMDClient('855d39510cce40caf11de4c941b37632d1529ec970156214528a33a0ae8473b4', 'http://127.0.0.1:6969')
if kmd_clt:
kmd_wlt_mdk = None
kmd_wlt_list = kmd_clt.list_wallets()
for kmd_wlt in kmd_wlt_list:
kmd_name = kmd_wlt['name']
kmd_id = kmd_wlt['id']
if kmd_name == 'wallet_name':
kmd_wlt_hdl = kmd_clt.init_wallet_handle(kmd_id, 'wallet_password')
if kmd_wlt_hdl:
kmd_wlt_mdk = kmd_clt.export_master_derivation_key(kmd_wlt_hdl, 'wallet_password')
break
if kmd_wlt_mdk:
kmd_wlt = kmd_clt.create_wallet('wallet_name', 'wallet_password', master_deriv_key=kmd_wlt_mdk)
kmd_wlt_hdl = kmd_clt.init_wallet_handle(kmd_wlt['id'], 'wallet_password')
acc_addr_list = kmd_clt.list_keys(kmd_wlt_hdl)
for acc_addr in acc_addr_list:
account_address = acc_addr
print(account_address)
account_key = kmd_clt.export_key(kmd_wlt_hdl, 'wallet_password', account_address)
print(account_key)
account_mnemonic = mnemonic.from_private_key(account_key)
print(account_mnemonic)
Below, you can watch at the Traceback and the error message returned at run-time:
Traceback (most recent call last):
File "/home/emiliano/anaconda3/lib/python3.7/site-packages/algosdk/kmd.py", line 63, in kmd_request
resp = urlopen(req)
File "/home/emiliano/anaconda3/lib/python3.7/urllib/request.py", line 222, in urlopen
return opener.open(url, data, timeout)
File "/home/emiliano/anaconda3/lib/python3.7/urllib/request.py", line 531, in open
response = meth(req, response)
File "/home/emiliano/anaconda3/lib/python3.7/urllib/request.py", line 641, in http_response
'http', request, response, code, msg, hdrs)
File "/home/emiliano/anaconda3/lib/python3.7/urllib/request.py", line 569, in error
return self._call_chain(*args)
File "/home/emiliano/anaconda3/lib/python3.7/urllib/request.py", line 503, in _call_chain
result = func(*args)
File "/home/emiliano/anaconda3/lib/python3.7/urllib/request.py", line 649, in http_error_default
raise HTTPError(req.full_url, code, msg, hdrs, fp)
urllib.error.HTTPError: HTTP Error 400: Bad Request
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/emiliano/anaconda3/lib/python3.7/site-packages/algosdk/kmd.py", line 67, in kmd_request
raise error.KMDHTTPError(json.loads(e)["message"])
algosdk.error.KMDHTTPError: wallet with same name already exists
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "algorand_test.py", line 49, in <module>
kmd_wlt = kmd_clt.create_wallet('emiliano', 'emiliano', master_deriv_key=kmd_wlt_mdk)
File "/home/emiliano/anaconda3/lib/python3.7/site-packages/algosdk/kmd.py", line 118, in create_wallet
return self.kmd_request("POST", req, data=query)["wallet"]
File "/home/emiliano/anaconda3/lib/python3.7/site-packages/algosdk/kmd.py", line 69, in kmd_request
raise error.KMDHTTPError(e)
algosdk.error.KMDHTTPError: {
"error": true,
"message": "wallet with same name already exists"
}
It seems to be clear how the create_wallet function is the sinner of such behavior which leads to get back the error "wallet with same name already exists". Internals of Algorand SDK are very simple, APIs are wrappers for REST methods. Function create_wallet does simply (link):
def create_wallet(self, name, pswd, driver_name="sqlite",
master_deriv_key=None):
"""
Create a new wallet.
Args:
name (str): wallet name
pswd (str): wallet password
driver_name (str, optional): name of the driver
master_deriv_key (str, optional): if recovering a wallet, include
Returns:
dict: dictionary containing wallet information
"""
req = "/wallet"
query = {
"wallet_driver_name": driver_name,
"wallet_name": name,
"wallet_password": pswd
}
if master_deriv_key:
query["master_derivation_key"] = master_deriv_key
return self.kmd_request("POST", req, data=query)["wallet"]
I'm sure the master derivation key passed in input is correct since I've alredy checked it with the goal command from console.
Has anyone else experienced this type of problem before?
To summarize, Algorand documentation of REST APIs doesn't suggest explicitly to use the Master-Derivation-Key to retrieve a Wallet when making a POST /v1/wallet (link). Conversely, Algorand documentation of Python SDK suggests that the Master-Derivation-Key can be passed to the create_wallet function, which then makes the HTTP POST stated before, to recover an existing Wallet (link).
As explained within my question above, create_wallet fails to recover the Wallet because the underlying POST /v1/wallet fails. At the suggestion of #Arty, this has been proved as follow:
curl -X POST -H "X-KMD-API-Token: <kmd-token>" -H "Content-Type: application/json" -d '{"wallet_driver_name": "sqlite", "wallet_name": <wallet-name>, "wallet_password": <wallet-password>, "master_derivation_key": <master-derivation-key>}' <kmd-address-and-port>/v1/wallet
which returned
{ "error": true, "message": "wallet with same name already exists" }
I notified this problem to the Algorand support and I'm currently waiting for a reply. Anyhow, in order to give some sense to the question's title, I want to share another possible solution to recover a Wallet still by relying on the Python SDK:
from algosdk import kmd
from algosdk import wallet
from algosdk import mnemonic
kmd_clt = kmd.KMDClient(<kmd-token>, <kmd-address-and-port>)
if kmd_clt:
kmd_wlt_mdk = None
kmd_wlt_list = kmd_clt.list_wallets()
for kmd_wlt in kmd_wlt_list:
kmd_name = kmd_wlt['name']
kmd_id = kmd_wlt['id']
if kmd_name == <wallet-name>:
kmd_wlt_hdl = kmd_clt.init_wallet_handle(kmd_id, <wallet-password>)
if kmd_wlt_hdl:
kmd_wlt_mdk = kmd_clt.export_master_derivation_key(kmd_wlt_hdl, <wallet-password>)
break
if kmd_wlt_mdk:
wlt = wallet.Wallet(<wallet-name>, <wallet-password>, kmd_clt, mdk=kmd_wlt_mdk)
if wlt:
acc_addr_list = wlt.list_keys()
for acc_addr in acc_addr_list:
account_address = acc_addr
print(account_address)
account_key = wlt.export_key(acc_addr)
print(account_key)
account_mnemonic = mnemonic.from_private_key(account_key)
print(account_mnemonic)
I hope it will be useful to someone else in the future.
I'm trying to use google-api-python-client 1.12.5 with Service account auth under Python 3.8. It seems to me that the when specifying the status parameter, Google responds with a 404 HTTP code. I can't figure out why. I also looked in the docs but I can't relate anything to this error.
I have pasted my code. The error is happening in the third call.
This is the code:
from google.oauth2 import service_account
from googleapiclient.discovery import build
SCOPES = ['https://www.googleapis.com/auth/blogger']
SERVICE_ACCOUNT_FILE = 'new_service_account.json'
BLOG_ID = '<your_blog_id>'
credentials = service_account.Credentials.from_service_account_file(
SERVICE_ACCOUNT_FILE, scopes=SCOPES)
service = build('blogger', 'v3', credentials=credentials)
p = service.posts()
# FIRST
promise = p.list(blogId=BLOG_ID)
result = promise.execute()
# SECOND
promise = p.list(blogId=BLOG_ID, orderBy='UPDATED')
result = promise.execute()
#THIRD
promise = p.list(blogId=BLOG_ID, orderBy='UPDATED', status='DRAFT')
result = promise.execute() # <===== ERROR HAPPENS HERE!!!!
service.close()
And this is the traceback:
Traceback (most recent call last):
File "/home/madtyn/.local/share/JetBrains/Toolbox/apps/PyCharm-P/ch-0/202.7660.27/plugins/python/helpers/pydev/pydevd.py", line 1448, in _exec
pydev_imports.execfile(file, globals, locals) # execute the script
File "/home/madtyn/.local/share/JetBrains/Toolbox/apps/PyCharm-P/ch-0/202.7660.27/plugins/python/helpers/pydev/_pydev_imps/_pydev_execfile.py", line 18, in execfile
exec(compile(contents+"\n", file, 'exec'), glob, loc)
File "/home/madtyn/PycharmProjects/blogger/main.py", line 24, in <module>
result = promise.execute()
File "/home/madtyn/venvs/blogger/lib/python3.8/site-packages/googleapiclient/_helpers.py", line 134, in positional_wrapper
return wrapped(*args, **kwargs)
File "/home/madtyn/venvs/blogger/lib/python3.8/site-packages/googleapiclient/http.py", line 915, in execute
raise HttpError(resp, content, uri=self.uri)
googleapiclient.errors.HttpError: <HttpError 404 when requesting https://blogger.googleapis.com/v3/blogs/<blog_id>/posts?orderBy=UPDATED&status=DRAFT&alt=json returned "Not Found">
python-BaseException
I can reproduce this issue... Adding status=DRAFT will return 404 but any other filter is working...
Tried with service account and your code: 404
Tried with API Key like this result = requests.get('https://blogger.googleapis.com/v3/blogs/<blog_id>/posts?status=DRAFT&orderBy=UPDATED&alt=json&key=<api_key>'): 404
Extracted "access_token" from service account (credentials.token after a call): result = requests.get('https://blogger.googleapis.com/v3/blogs/<blog_id>/posts?status=DRAFT&orderBy=UPDATED&alt=json&access_token=<extracted_service_account_token>'): 404
But very strangely if I use access_token given by "Try this API" here : https://developers.google.com/blogger/docs/3.0/reference/posts/list?apix_params={"blogId"%3A"blog_id"%2C"orderBy"%3A"UPDATED"%2C"status"%3A["DRAFT"]%2C"alt"%3A"json"} it's works !
Used that token with requests give me my blog post in draft status...
Just copy/paste raw Authorization header inside that script:
import requests
blog_id = '<blog_id>'
headers = {
'Authorization' : 'Bearer <replace_here>'
}
# Using only Authorization header
result = requests.get(
'https://blogger.googleapis.com/v3/blogs/%s/posts?status=DRAFT&orderBy=UPDATED&alt=json' % (blog_id),
headers=headers
)
print(result)
# This should print DRAFT if you have at least one draft post
print(result.json()['items'][0]['status'])
# Using "access_token" param constructed with Authorization header splited to have only token
result = requests.get('https://blogger.googleapis.com/v3/blogs/%s/posts?status=DRAFT&orderBy=UPDATED&alt=json&access_token=%s' % (blog_id, headers['Authorization'][len('Bearer '):]))
print(result)
# This should print DRAFT if you have at least one draft post
print(result.json()['items'][0]['status'])
Results I have currently:
The bug doesn't seem to come from the library but rather from the token rights...However I also used the console normally to generate accesses like you.
To conclude I think it's either a bug or it's voluntary from Google... I don't know how long the "Try this API" token is valid but it is currently the only way I found to get the draft articles... Maybe you can try to open a bug ticket but I don't know specifically where it is possible to do that.
I'm trying to use SharePlum which is a Python module for SharePoint but when I try to connect to my SharePoint, SharePlum raises me this error:
Traceback (most recent call last):
File "C:/Users/me/Desktop/Sharpoint/sharpoint.py", line 13, in site = Site(sharepoint_url, auth=auth)
File "C:\Users\me\AppData\Local\Programs\Python\Python36\lib\site-packages\shareplum\shareplum.py", line 46, in init self.users = self.GetUsers()
File "C:\Users\me\AppData\Local\Programs\Python\Python36\lib\site-packages\shareplum\shareplum.py", line 207, in GetUsers raise Exception("Can't get User Info List")
Exception: Can't get User Info List
Here is the very short code that I have written:
auth = HttpNtlmAuth(username, password)
site = Site(sharepoint_url, auth=auth)
This error seems to indicate bad username/password but I'm pretty sure that the one I have are correct...
Ok, it seems that I found the solution for my problem, it's about the Sharepoint URL that I gave.
If we take this example : https://www.mysharepoint.com/Your/SharePoint/DocumentLibrary
You have to remove the last part : /DocumentLibrary.
Why remove this part precisely ?
In fact, when you go deep enough in your Sharepoint, your url will look like something like : https://www.mysharepoint.com/Your/SharePoint/DocumentLibrary/Forms/AllItems.aspx?RootFolder=%2FYour%2FSharePoint%2DocumentLibrary%2FmyPersonnalFolder&FolderCTID=0x0120008BBC54784D92004D1E23F557873CC707&View=%7BE149526D%2DFD1B%2D4BFA%2DAA46%2D90DE0770F287%7D
You can see that the right of the path is in RootFolder=%2FYour%2FSharePoint%2DocumentLibrary%2Fmy%20personnal%20folder and not in the "normal" URL anymore (if it were, it will be like that https://www.mysharepoint.com/Your/SharePoint/DocumentLibrary/myPersonnalFolder/).
What you have to remove is the end of the "normal" URL so in this case, /DocumentLibrary.
So my correct Sharepoint URL to input in SharePlum will be https://www.mysharepoint.com/Your/SharePoint/
I'm pretty new to Sharepoint so I'm not really sure that this I the right answer to this problem for the others persons, may someone who know Sharepoint better than me can confirm ?
I know this is not actual solution for your problem and I would add just comment but it was too long so I will post as answer.
I can't replicate your issue, but by looking into source code of shareplum.py you can see why program throws the error. In line 196 of shareplum.py there is if clause (if response.status_code == 200:) which checks if the request to access your sharepoint url was successful (than it has status code 200) and if request failed (than it has some other status code) than it throws exception (Can't get User Info List). If you want to find out more about your problem go to your shareplum.py file ("C:\Users\me\AppData\Local\Programs\Python\Python36\lib\site-packages\shareplum\shareplum.py") and add this line print('{} {} Error: {} for url: {}'.format(response.status_code, 'Client'*(400 <= response.status_code < 500) + 'Server'*(500 <= response.status_code < 600), response.reason, response.url)) before line 207 ('raise Exception("Can't get User Info List")'). Then your shareplum.py should look like this:
# Parse Response
if response.status_code == 200:
envelope = etree.fromstring(response.text.encode('utf-8'))
listitems = envelope[0][0][0][0][0]
data = []
for row in listitems:
# Strip the 'ows_' from the beginning with key[4:]
data.append({key[4:]: value for (key, value) in row.items() if key[4:]})
return {'py': {i['ImnName']: i['ID']+';#'+i['ImnName'] for i in data},
'sp': {i['ID']+';#'+i['ImnName'] : i['ImnName'] for i in data}}
else:
print('{} {} Error: {} for url: {}'.format(response.status_code, 'Client'*(400 <= response.status_code < 500) + 'Server'*(500 <= response.status_code < 600), response.reason, response.url))
raise Exception("Can't get User Info List")
Now just run your program again and it should print out why it isn't working.
I know it is best not to change files in Python modules, but if you know what you change then there is no problem so when you are finished just delete the added line.
Also when you find out status code you can search it online, just type it in google or search on List_of_HTTP_status_codes.
This question already has an answer here:
Python GAE urlfetch credentials
(1 answer)
Closed 7 years ago.
GAE Python URL Fetch throws InvalidURLError while the same URL works perfectly with Postman ( Google Chrome App ).
CODE
url = "https://abcdefgh:28dfd95928dfd95928dfd95928dfd95928dfd95928dfd959#twilix.exotel.in/v1/Accounts/abcdefgh/Sms/send"
form_fields = {
"From": "08039511111",
"To": "+919844100000",
"Body": "message for you"
}
form_data = urllib.urlencode (form_fields)
try:
result = urlfetch.fetch(url=url,
payload=form_data,
method=urlfetch.POST,
headers={'Content-Type': 'application/x-www-form-urlencoded' }
)
logging.info ("result = ["+repr (result)+"] ")
except Exception:
logging.error ("Exception. ["+traceback.format_exc ()+"] ")
OUTPUT LOGS
2016-01-21 15:48:23.368 +0530 E Exception. [
Traceback (most recent call last): File "main.py", line 27, in get method=urlfetch.POST,
File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/api/urlfetch.py", line 271, in fetch return rpc.get_result()
File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/api/apiproxy_stub_map.py", line 613, in get_result return self.__get_result_hook(self)
File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/api/urlfetch.py", line 389, in _get_fetch_result 'Invalid request URL: ' + url + error_detail) InvalidURLError: Invalid request URL: https://abcdefgh:28dfd95928dfd95928dfd95928dfd95928dfd95928dfd959#twilix.exotel.in/v1/Accounts/abcdefgh/Sms/send ]
For security purpose, I have replaced sensitive text in the URL with similar different characters.
The code indicates an INVALID_URL RPC error code was received from the urlfetch service.
The most common occurence seems to be due to the URL length limit (check if your unedited URL hits that): Undocumented max length for urlfetch URL?
A long time ago it was also seen for very slow URLs (in Go land, but I suspect the urlfetch service itself is the same serving all language sandboxes) - unsure if this still stands, I also see a DEADLINE_EXCEEDED error code as well which might have been introduced specifically for such case in the meantime): Google App Engine Go HTTP request to a slow page
The failure might also be related to incorrect parsing of the rather unusual "host" portion of your URL foo:blah#hostname. Check if it you're getting the same error if dropping the foo:blah# portion. If it's indeed the case you might want to file an issue with Google - the URL seems valid, works with curl as well.
I found the problem and the solution.
We need to specify the HTTP auth info using headers.
urlfetch.make_fetch_call ( rpc,
url,
method = urlfetch.POST,
headers = { "Authorization" : "Basic %s" % base64.b64encode ( URL_USERNAME+":"+URL_PASSOWRD ) },
)
Courtesy
https://stackoverflow.com/a/8454580/1443563 by raugfer
So I'm working with a block of code which communicates with the Flickr API.
I'm getting a 'syntax error' in xml.parsers.expat.ExpatError (below). Now I can't figure out how it'd be a syntax error in a Python module.
I saw another similar question on SO regarding the Wikipedia API which seemed to return HTML intead of XML. Flickr API returns XML; and I'm also getting the same error when there shouldn't be a response from Flickr (such as flickr.galleries.addPhoto)
CODE:
def _dopost(method, auth=False, **params):
#uncomment to check you aren't killing the flickr server
#print "***** do post %s" % method
params = _prepare_params(params)
url = '%s%s/%s' % (HOST, API, _get_auth_url_suffix(method, auth, params))
payload = 'api_key=%s&method=%s&%s'% \
(API_KEY, method, urlencode(params))
#another useful debug print statement
#print url
#print payload
return _get_data(minidom.parse(urlopen(url, payload)))
TRACEBACK:
Traceback (most recent call last):
File "TESTING.py", line 30, in <module>
flickr.galleries_create('test_title', 'test_descriptionn goes here.')
File "/home/vlad/Documents/Computers/Programming/LEARNING/curatr/flickr.py", line 1006, in galleries_create
primary_photo_id=primary_photo_id)
File "/home/vlad/Documents/Computers/Programming/LEARNING/curatr/flickr.py", line 1066, in _dopost
return _get_data(minidom.parse(urlopen(url, payload)))
File "/usr/lib/python2.6/xml/dom/minidom.py", line 1918, in parse
return expatbuilder.parse(file)
File "/usr/lib/python2.6/xml/dom/expatbuilder.py", line 928, in parse
result = builder.parseFile(file)
File "/usr/lib/python2.6/xml/dom/expatbuilder.py", line 207, in parseFile
parser.Parse(buffer, 0)
xml.parsers.expat.ExpatError: syntax error: line 1, column 62
(Code from http://code.google.com/p/flickrpy/ under New BSD licence)
UPDATE:
print urlopen(url, payload) == <addinfourl at 43340936 whose fp = <socket._fileobject object at 0x29400d0>>
Doing a urlopen(url, payload).read() returns HTML which is hard to read in a terminal :P but I managed to make out a 'You are not signed in.'
The strange part is that Flickr shouldn't return anything here, or if permissions are a problem, it should return a 99: User not logged in / Insufficient permissions error as it does with the GET function (which I'd expect would be in valid XML).
I'm signed in to Flickr (in the browser) and the program is properly authenticated with delete permissions (dangerous, but I wanted to avoid permission problems.)
SyntaxError normally means an error in Python syntax, but I think here that expatbuilder is overloading it to mean an XML syntax error. Put a try:except block around it, and print out the contents of payload and to work out what's wrong with the first line of it.
My guess would be that flickr is rejecting your request for some reason and giving back a plain-text error message, which has an invalid xml character at column 62, but it could be any number of things. You probably want to check the http status code before parsing it.
Also, it's a bit strange this method is called _dopost but you seem to actually be sending an http GET. Perhaps that's why it's failing.
This seems to fix my problem:
url = '%s%s/?api_key=%s&method=%s&%s'% \
(HOST, API, API_KEY, method, _get_auth_url_suffix(method, auth, params))
payload = '%s' % (urlencode(params))
It seems that the API key and method had to be in the URL not in the payload. (Or maybe only one needed to be there, but anyways, it works :-)