Twitpic will only 400 Bad Request you if it can't find the image in your multipart/form- data or if the image is invalid (not jpg/png/gif or >5MB in size).
Thanks, Steve C Twitpic On Jun 4, 9:20 am, Yann Malet <yann.ma...@gmail.com> wrote: > If I send this request to 127.0.0.1:9000 without the file here it is the > string I can observe : > > """ > (ve)y...@yml-laptop:jess3$ netcat -l -p 9000 > POST / HTTP/1.1 > Accept-Encoding: identity > Content-Length: 377 > X-Auth-Service-Provider:https://api.twitter.com/1/account/verify_credentials.json > Host: 127.0.0.1:9000 > User-Agent: Python-urllib/2.6 > Connection: close > Content-Type: multipart/form-data; boundary=a45bd25da2844dac81003987b3c19e18 > X-Verify-Credentials-Authorization: OAuth realm="http://api.twitter.com/", > oauth_signature_method="HMAC-SHA1", > oauth_consumer_key="y2hEqGNEmyjU2De3hNcg", > oauth_token="90476798-5VZeNLpXUCaJ06UaWve2c4JVfdcJj5D4r21JxUFM", > oauth_signature="NMPlU4cRYl0b6jbQJ1xGXaZ5%2FpM%3D" > > --a45bd25da2844dac81003987b3c19e18 > Content-Disposition: form-data; name="key" > Content-Type: text/plain; charset=utf-8 > Content-Length: 32 > > 4bb040d1ec65427f8038cdd60a12cde2 > --a45bd25da2844dac81003987b3c19e18 > Content-Disposition: form-data; name="message" > Content-Type: text/plain; charset=utf-8 > Content-Length: 13 > > copine et moi > --a45bd25da2844dac81003987b3c19e18-- > ^C > (ve)y...@yml-laptop:jess3$ > > """ > > Does any one can spot the issue ? > Regards, > --yml > > > > On Fri, Jun 4, 2010 at 9:14 AM, Yann Malet <yann.ma...@gmail.com> wrote: > > Hello Zac, > > > I rewrote everything in my app based on python-oauth2 : > >http://dpaste.com/203168/ > > The file is still hardcoded to ease the comprehension. I hope this will > > help you to spot my issue. > > > The error message I get from twitpic is 400 bad request. > > Regards, > > --yml > > > """ > > class OAuthEchoRequest(oauth.Request): > > def to_header(self, realm='http://api.twitter.com/'): > > headers = super(OAuthEchoRequest, self).to_header(realm=realm) > > return {'X-Verify-Credentials-Authorization': > > headers['Authorization']} > > > @login_required > > def twitpic_upload_photo(request): > > if request.method == 'POST': > > form = PhotoForm(request.POST, request.FILES) > > if form.is_valid(): > > profile = Profile.objects.get(user=request.user) > > token = oauth.Token(profile.oauth_token, > > profile.oauth_secret) > > > params = { > > 'oauth_consumer_key': settings.TWITTER_CONSUMER_KEY, > > 'oauth_signature_method':"HMAC-SHA1", > > 'oauth_token':token.key, > > 'oauth_timestamp':oauth.generate_timestamp(), > > 'oauth_nonce':oauth.generate_nonce(), > > 'oauth_version':'1.0' > > } > > > oauth_echo_request = OAuthEchoRequest(method="GET", > > > url=settings.TWITTER_VERIFY_CREDENTIALS, > > #parameters=params > > ) > > > signature=oauth_echo_request.sign_request(oauth.SignatureMethod_HMAC_SHA1() > > , > > consumer, > > token) > > > headers = oauth_echo_request.to_header() > > headers['X-Auth-Service-Provider'] = > > settings.TWITTER_VERIFY_CREDENTIALS > > > #with multipart_encode > > values = [ > > MultipartParam('key',value=settings.TWITPIC_API_KEY), > > > MultipartParam('message',value=form.cleaned_data['message']), > > MultipartParam('media', > > filename='copine_moi.jpg', > > filetype='image/jpeg', > > > fileobj=open("/home/yml/Desktop/copine_moi.jpg","rb")) > > ] > > > register_openers() > > datagen, heads = multipart_encode(values) > > headers.update(heads) > > req = urllib2.Request(settings.TWITPIC_API_URL, datagen, > > headers) > > # Post to netcat > > #req = urllib2.Request("http://127.0.0.1:9000", datagen, > > headers) > > > #with urlencode > > #values = {} > > #values['key'] = MultipartParam(settings.TWITPIC_API_KEY) > > #values['message'] = > > MultipartParam(form.cleaned_data['message']) > > #values['media'] = open("/home/yml/Desktop/copine_moi.jpg", > > "rb").read() > > #data = urllib.urlencode(values) > > #req = urllib2.Request(settings.TWITPIC_API_URL, data, headers) > > > response = urllib2.urlopen(req) > > > return HttpResponse("the photo is posted") > > else: > > form = PhotoForm() > > > return direct_to_template(request, > > "twitter_integration/photo_form.html", > > {"form":form,}) > > """ > > > On Thu, Jun 3, 2010 at 10:48 PM, Zac Bowling <zbowl...@gmail.com> wrote: > > >> Hi Yann, > > >> I don't see anything obvious that stands out as wrong to me in your > >> implementation from just looking at it, but I'm not sure. I do have OAuth > >> Echo code working for Twitpic but using the OAuth2 library. If you don't > >> figure out an answer, you can hit me up off the list and I'll see if I > >> separate our version so it works independently and I'll post it on gist for > >> you. > > >> If you want to upgrade though to python-oauth2, the biggest change is > >> swapping out your imports to use oauth2 instead of oauth and removing the > >> "OAuth" prefix on all the class names. > > >> For example: > >> import oauth > >> oauth.OAuthRequest(...) > >> oauth.OAuthToken(...) > > >> becomes: > >> import oauth2 > >> oauth2.Request(...) > >> oauth2.Token(...) > > >> etc... > > >> Most of the API that you care about is identical from there. The library > >> has evolved a bit but it should be obvious and most of the public methods > >> remained the same. In my fork, I've fixed a few issues and added some > >> changes to support XAuth and a few other minor issues (like forcing > >> Authentication headers on POSTs for Twitter). > > >> Zac Bowling > >> @zbowling > > >> On Jun 3, 2010, at 6:37 PM, Yann Malet wrote: > > >> Zac, > >> I would love to do this but I can't find any documentation on how to do > >> Oauth Echo with python-oauth2. I would gladly switch to python-ouath2 if I > >> could find some code showing How to use it to post a picture on twitpic : > >>http://dev.twitpic.com/docs/2/upload/ > > >> <http://dev.twitpic.com/docs/2/upload/>Any help would be greatly > >> appreciated. > >> Regards, > >> --yml > > >> On Thu, Jun 3, 2010 at 7:41 PM, Zac Bowling <zbowl...@gmail.com> wrote: > > >>> It may not help fix your problem but I would recommend upgrading to the > >>> python-oauth2 library. (Don't be confused by the name; it's not an oauth > >>> 2.0 > >>> library, but just the next generation of the original oauth 1.0a library > >>> that Leah Culver wrote). There are bunch of little issues with the > >>> original > >>> one that don't follow the spec exactly that are fixed and it's not a > >>> difficult upgrade (as long as your are not hosting an OAuth server of your > >>> own because those interfaces changed considerably). > > >>>http://github.com/zbowling/python-oauth2(the fork I maintain with bunch > >>> of twitter related fixes and workarounds) > >>> or: > >>>http://github.com/simplegeo/python-oauth2(the official upstream) > > >>> Zac Bowling > >>> @zbowling > > >>> On Jun 3, 2010, at 3:15 PM, Steve C wrote: > > >>> > I just looked at your code briefly, but I believe the problem is this > >>> > line: > > >>> > oauth_request = TwitpicOAuthRequest(http_method="POST", > >>> > http_url=settings.TWITPIC_API_URL, > > >>> > The OAuth Request needs to be signed using the Twitter Endpoint > >>> > (https://api.twitter.com/1/account/verify_credentials.json), not the > >>> > Twitpic API URL. > > >>> > Try something like this: > > >>> > oauth_request = TwitpicOAuthRequest(http_method="GET", > >>> > http_url="https://api.twitter.com/1/account/verify_credentials.json", > > >>> > On Jun 3, 2:38 pm, yml <yann.ma...@gmail.com> wrote: > >>> >> I would greatly appreciate any help. > >>> >> Here it is the latest evolution of this piece of code : > > >>> >> """ > >>> >> class TwitpicOAuthRequest(OAuthRequest): > >>> >> def to_header(self, realm='http://api.twitter.com/'): > >>> >> headers = super(TwitpicOAuthRequest, > >>> >> self).to_header(realm=realm) > >>> >> return {'X-Verify-Credentials-Authorization': > >>> >> headers['Authorization']} > > >>> >> def post_photo(request): > >>> >> if request.method == 'POST': > >>> >> form = PhotoForm(request.POST, request.FILES) > >>> >> if not request.session.get('twitter_access_token'): > >>> >> return HttpResponse("Not authenticated") > >>> >> if form.is_valid(): > >>> >> access_token = request.session['twitter_access_token'] > > >>> >> params = { > >>> >> 'oauth_consumer_key': settings.TWITTER_CONSUMER_KEY, > >>> >> 'oauth_signature_method':"HMAC-SHA1", > >>> >> 'oauth_token':access_token.key, > >>> >> 'oauth_timestamp':oauth.generate_timestamp(), > >>> >> 'oauth_nonce':oauth.generate_nonce(), > >>> >> 'oauth_version':'1.0' > >>> >> } > > >>> >> consumer = > >>> >> oauth.OAuthConsumer(key=settings.TWITTER_CONSUMER_KEY, > > >>> >> secret=settings.TWITTER_CONSUMER_SECRET) > >>> >> token = oauth.OAuthToken(key=access_token.key, > >>> >> secret=access_token.secret) > >>> >> oauth_request = TwitpicOAuthRequest(http_method="GET", > > >>> >> #http_url=settings.TWITPIC_API_URL, > > >>> >> http_url=settings.TWITTER_VERIFY_CREDENTIALS, > >>> >> parameters=params) > > >>> >> signature=oauth_request.sign_request(OAuthSignatureMethod_HMAC_SHA1(), > >>> >> consumer, > >>> >> access_token) > > >>> >> headers = oauth_request.to_header() > >>> >> headers['X-Auth-Service-Provider'] = > >>> >> settings.TWITTER_VERIFY_CREDENTIALS > > >>> >> #with multipart_encode > >>> >> values = [ > >>> >> > >>> >> MultipartParam('key',value=settings.TWITPIC_API_KEY),... > > read more »