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), >>> >> >>> >> 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 -l -p 9000 >>> >> #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(initial={"created_at":datetime.now()}) >>> >> >>> >> return render_to_response("twitter_integration/photo_form.html", >>> >> {"form":form,}, >>> >> >>> >> context_instance=RequestContext(request)) >>> >> """ >>> >> >>> >> On Jun 3, 11:20 am, yml <yann.ma...@gmail.com> wrote: >>> >> >>> >> >>> >> >>> >>> Hello, >>> >>> I am in the process of writing a python web app that should enable >>> the >>> >>> user to post picture to twitpic using the Oauth Echo authorization >>> >>> mechanism. >>> >> >>> >>> The application is already able to post tweet using the Oauth >>> >>> authentication so the access_token is available to us in the session. >>> >> >>> >>> So my question to you guys is that it would be great if someone could >>> >>> point what is the issue in the code below or paste some sample code >>> >>> that upload a picture in python to twitpic. >>> >> >>> >>> """" >>> >>> # OauthRequest is from the python-oauth lib >>> >>> # I overide the to_header method to return a dict with the right key. >>> >> >>> >>> 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="POST", >>> >> >>> >>> http_url=settings.TWITPIC_API_URL, >>> >>> parameters=params) >>> >> >>> >>> >>> signature=oauth_request.build_signature(OAuthSignatureMethod_HMAC_SHA1(), >>> >>> consumer, >>> >>> access_token) >>> >> >>> >>> headers = oauth_request.to_header() >>> >>> headers['X-Auth-Service-Provider'] = 'https:// >>> >>> api.twitter.com/1/account/verify_credentials.json' >>> >>> headers['X-Verify-Credentials-Authorization'] += ', >>> >>> oauth_signature="%s"' %signature >>> >> >>> >>> values = {} >>> >>> values['key'] = settings.TWITPIC_API_KEY >>> >>> values['message'] = form.cleaned_data['message'] >>> >>> # the path to the file is hardcoded here in the future it >>> >>> will be taken from the from >>> >>> values['media'] = >>> 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) >>> >>> response = urllib2.urlopen(req) >>> >> >>> >>> return HttpResponse("the photo is posted") >>> >>> else: >>> >>> form = PhotoForm(initial={"created_at":datetime.now()}) >>> >> >>> >>> return render_to_response("twitter_integration/photo_form.html", >>> >>> {"form":form,}, >>> >> >>> >>> context_instance=RequestContext(request)) >>> >>> """" >>> >>> >> >> >