Get raw thumbnail using rest api

How do you get the raw thumbnail URL using the rest api? This is how i do it in python but im not entirely clear how to do this exact thing using the REST Api.

def getFullRawThumbnail():
    entityID = 423
    rawFile = sg.get_attachment_download_url({'url':'https://******.shotgunstudio.com/thumbnail/full/CustomNonProjectEntity08/{}'.format(entityID)})
    os.startfile(rawFile)
    print rawFile
2 Likes

One of our engineers made an upload/download sample here:

You should be able to substitute the url variable in the example with the above URL and get the same result.

1 Like

I’m trying to display the full res thumbnail inside of another webpage I’ve created. So i need a direct path to the image.

1 Like

I get the following error when translating his code into using the REST API with javascript.

.get(
"https://#######.shotgunstudio.com/api/v1/entity/CustomNonProjectEntity08/56/image?alt=original",
    {
      headers: {
        Accept: 'application/json',
        'Content-Type': 'application/vnd+shotgun.api3_array+json',
        Authorization: `Bearer ${ACCESS_TOKEN}`
      }
    }
  )

Code: InvalidArgument
Message: Only one auth mechanism allowed; only the X-Amz-Algorithm query parameter, Signature query string parameter or the Authorization header should be specified
ArgumentName: Authorization
ArgumentValue: Bearer ***
RequestId: 18703410875B9666
HostId: ****=

1 Like

What happens if you instead try to .get:

https://#######.shotgunstudio.com/thumbnail/full/CustomNonProjectEntity08/56
1 Like

That does not error, it actually returns a result but the result appears to be a string that contains and entire html page…? :slight_smile:

This url is closer to the one i used in my original python sample. But i passed it an arg of ‘url’ to get the raw image path.

<!DOCTYPE html>
<html lang="en" class="sg_reset_html sgds-theme-root sgds-theme-root--default">
<head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8">
<script>window.NREUM||(NREUM={});NREUM.info={"beacon":"bam.nr-data.net","errorBeacon":"bam.nr-data.net","licenseKey":"55c4dcc6d9","applicationID":"584126040,378694362","transactionName":"clpWERYMCV1XEx5GSlRHFwkLBAxf","queueTime":1,"applicationTime":23,"agent":""}</script>
<script>(window.NREUM||(NREUM={})).loader_config={licenseKey:"55c4dcc6d9",applicationID:"584126040"};window.NREUM||(NREUM={}),__nr_require=function(e,n,t){function r(t){if(!n[t]){var i=n[t]={exports:{}};e[t][0].call(i.exports,function(n){var i=e[t][1][n];return r(i||n)},i,i.exports)}return n[t].exports}if("function"==typeof __nr_require)return __nr_require;for(var i=0;i<t.length;i++)r(t[i]);return r}({1:[function(e,n,t){function r(){}function i(e,n,t){return function(){return o(e,[u.now()].concat(f(arguments)),n?null:this,t),n?void 0:this}}var o=e("handle"),a=e(4),f=e(5),c=e("ee").get("tracer"),u=e("loader"),s=NREUM;"undefined"==typeof window.newrelic&&(newrelic=s);var p=["setPageViewName","setCustomAttribute","setErrorHandler","finished","addToTrace","inlineHit","addRelease"],l="api-",d=l+"ixn-";a(p,function(e,n){s[n]=i(l+n,!0,"api")}),s.addPageAction=i(l+"addPageAction",!0),s.setCurrentRouteName=i(l+"routeName",!0),n.exports=newrelic,s.interaction=function(){return(new r).get()};var m=r.prototype={createTracer:function(e,n){var t={},r=this,i="function"==typeof n;return o(d+"tracer",[u.now(),e,t],r),function(){if(c.emit((i?"":"no-")+"fn-start",[u.now(),r,i],t),i)try{return n.apply(this,arguments)}catch(e){throw c.emit("fn-err",[arguments,this,e],t),e}finally{c.emit("fn-end",[u.now()],t)}}}};a("actionText,setName,setAttribute,save,ignore,onEnd,getContext,end,get".split(","),function(e,n){m[n]=i(d+n)}),newrelic.noticeError=function(e,n){"string"==typeof e&&(e=new Error(e)),o("err",[e,u.now(),!1,n])}},{}],2:[function(e,n,t){function r(e,n){var t=e.getEntries();t.forEach(function(e){"first-paint"===e.name?c("timing",["fp",Math.floor(e.startTime)]):"first-contentful-paint"===e.name&&c("timing",["fcp",Math.floor(e.startTime)])})}function i(e,n){var t=e.getEntries();t.length>0&&c("lcp",[t[t.length-1]])}function o(e){if(e instanceof s&&!l){var n,t=Math.round(e.timeStamp);n=t>1e12?Date.now()-t:u.now()-t,l=!0,c("timing",["fi",t,{type:e.type,fid:n}])}}if(!("init"in NREUM&&"page_view_timing"in NREUM.init&&"enabled"in NREUM.init.page_view_timing&&NREUM.init.page_view_timing.enabled===!1)){var a,f,c=e("handle"),u=e("loader"),s=NREUM.o.EV;if("PerformanceObserver"in window&&"function"==typeof window.PerformanceObserver){a=new PerformanceObserver(r),f=new PerformanceObserver(i);try{a.observe({entryTypes:["paint"]}),f.observe({entryTypes:["largest-contentful-paint"]})}catch(p){}}if("addEventListener"in document){var l=!1,d=["click","keydown","mousedown","pointerdown","touchstart"];d.forEach(function(e){document.addEventListener(e,o,!1)})}}},{}],3:[function(e,n,t){function r(e,n){if(!i)return!1;if(e!==i)return!1;if(!n)return!0;if(!o)return!1;for(var t=o.split("."),r=n.split("."),a=0;a<r.length;a++)if(r[a]!==t[a])return!1;return!0}var i=null,o=null,a=/Version\/(\S+)\s+Safari/;if(navigator.userAgent){var f=navigator.userAgent,c=f.match(a);c&&f.indexOf("Chrome")===-1&&f.indexOf("Chromium")===-1&&(i="Safari",o=c[1])}n.exports={agent:i,version:o,match:r}},{}],4:[function(e,n,t){function r(e,n){var t=[],r="",o=0;for(r in e)i.call(e,r)&&(t[o]=n(r,e[r]),o+=1);return t}var i=Object.prototype.hasOwnProperty;n.exports=r},{}],5:[function(e,n,t){function r(e,n,t){n||(n=0),"undefined"==typeof t&&(t=e?e.length:0);for(var r=-1,i=t-n||0,o=Array(i<0?0:i);++r<i;)o[r]=e[n+r];return o}n.exports=r},{}],6:[function(e,n,t){n.exports={exists:"undefined"!=typeof window.performance&&window.performance.timing&&"undefined"!=typeof window.performance.timing.navigationStart}},{}],ee:[function(e,n,t){function r(){}function i(e){function n(e){return e&&e instanceof r?e:e?c(e,f,o):o()}function t(t,r,i,o){if(!l.aborted||o){e&&e(t,r,i);for(var a=n(i),f=v(t),c=f.length,u=0;u<c;u++)f[u].apply(a,r);var p=s[y[t]];return p&&p.push([b,t,r,a]),a}}function d(e,n){h[e]=v(e).concat(n)}function m(e,n){var t=h[e];if(t)for(var r=0;r<t.length;r++)t[r]===n&&t.splice(r,1)}function v(e){return h[e]||[]}function g(e){return p[e]=p[e]||i(t)}function w(e,n){u(e,function(e,t){n=n||"feature",y[t]=n,n in s||(s[n]=[])})}var h={},y={},b={on:d,addEventListener:d,removeEventListener:m,emit:t,get:g,listeners:v,context:n,buffer:w,abort:a,aborted:!1};return b}function o(){return new r}function a(){(s.api||s.feature)&&(l.aborted=!0,s=l.backlog={})}var f="nr@context",c=e("gos"),u=e(4),s={},p={},l=n.exports=i();l.backlog=s},{}],gos:[function(e,n,t){function r(e,n,t){if(i.call(e,n))return e[n];var r=t();if(Object.defineProperty&&Object.keys)try{return Object.defineProperty(e,n,{value:r,writable:!0,enumerable:!1}),r}catch(o){}return e[n]=r,r}var i=Object.prototype.hasOwnProperty;n.exports=r},{}],handle:[function(e,n,t){function r(e,n,t,r){i.buffer([e],r),i.emit(e,n,t)}var i=e("ee").get("handle");n.exports=r,r.ee=i},{}],id:[function(e,n,t){function r(e){var n=typeof e;return!e||"object"!==n&&"function"!==n?-1:e===window?0:a(e,o,function(){return i++})}var i=1,o="nr@id",a=e("gos");n.exports=r},{}],loader:[function(e,n,t){function r(){if(!x++){var e=E.info=NREUM.info,n=d.getElementsByTagName("script")[0];if(setTimeout(s.abort,3e4),!(e&&e.licenseKey&&e.applicationID&&n))return s.abort();u(y,function(n,t){e[n]||(e[n]=t)}),c("mark",["onload",a()+E.offset],null,"api");var t=d.createElement("script");t.src="https://"+e.agent,n.parentNode.insertBefore(t,n)}}function i(){"complete"===d.readyState&&o()}function o(){c("mark",["domContent",a()+E.offset],null,"api")}function a(){return O.exists&&performance.now?Math.round(performance.now()):(f=Math.max((new Date).getTime(),f))-E.offset}var f=(new Date).getTime(),c=e("handle"),u=e(4),s=e("ee"),p=e(3),l=window,d=l.document,m="addEventListener",v="attachEvent",g=l.XMLHttpRequest,w=g&&g.prototype;NREUM.o={ST:setTimeout,SI:l.setImmediate,CT:clearTimeout,XHR:g,REQ:l.Request,EV:l.Event,PR:l.Promise,MO:l.MutationObserver};var h=""+location,y={beacon:"bam.nr-data.net",errorBeacon:"bam.nr-data.net",agent:"js-agent.newrelic.com/nr-1167.min.js"},b=g&&w&&w[m]&&!/CriOS/.test(navigator.userAgent),E=n.exports={offset:f,now:a,origin:h,features:{},xhrWrappable:b,userAgent:p};e(1),e(2),d[m]?(d[m]("DOMContentLoaded",o,!1),l[m]("load",r,!1)):(d[v]("onreadystatechange",i),l[v]("onload",r)),c("mark",["firstbyte",f],null,"api");var x=0,O=e(6)},{}],"wrap-function":[function(e,n,t){function r(e){return!(e&&e instanceof Function&&e.apply&&!e[a])}var i=e("ee"),o=e(5),a="nr@original",f=Object.prototype.hasOwnProperty,c=!1;n.exports=function(e,n){function t(e,n,t,i){function nrWrapper(){var r,a,f,c;try{a=this,r=o(arguments),f="function"==typeof t?t(r,a):t||{}}catch(u){l([u,"",[r,a,i],f])}s(n+"start",[r,a,i],f);try{return c=e.apply(a,r)}catch(p){throw s(n+"err",[r,a,p],f),p}finally{s(n+"end",[r,a,c],f)}}return r(e)?e:(n||(n=""),nrWrapper[a]=e,p(e,nrWrapper),nrWrapper)}function u(e,n,i,o){i||(i="");var a,f,c,u="-"===i.charAt(0);for(c=0;c<n.length;c++)f=n[c],a=e[f],r(a)||(e[f]=t(a,u?f+i:i,o,f))}function s(t,r,i){if(!c||n){var o=c;c=!0;try{e.emit(t,r,i,n)}catch(a){l([a,t,r,i])}c=o}}function p(e,n){if(Object.defineProperty&&Object.keys)try{var t=Object.keys(e);return t.forEach(function(t){Object.defineProperty(n,t,{get:function(){return e[t]},set:function(n){return e[t]=n,n}})}),n}catch(r){l([r])}for(var i in e)f.call(e,i)&&(n[i]=e[i]);return n}function l(n){try{e.emit("internal-error",n)}catch(t){}}return e||(e=i),t.inPlace=u,t.flag=a,t}},{}]},{},["loader"]);</script>
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">

    <title>Shotgun</title>

    <!-- Favicon for different platforms -->
<!-- This partial should be included in the head section of the root html file -->
<link rel="shortcut icon" href="/images/favicon/shotgun-icon-64x64.ico">

<link rel="icon" type="image/png" sizes="310x310" href="/images/favicon/shotgun-icon-310x310.png">


<link rel="apple-touch-icon" href="/images/favicon/shotgun-icon-64x64.png">

<link rel="apple-touch-icon" sizes="310x310" href="/images/favicon/shotgun-icon-310x310.png">
<link rel="apple-touch-icon" sizes="64x64" href="/images/favicon/shotgun-icon-64x64.png">
<link rel="apple-touch-icon" sizes="48x48" href="/images/favicon/shotgun-icon-48x48.png">
<link rel="apple-touch-icon" sizes="32x32" href="/images/favicon/shotgun-icon-32x32.png">
<link rel="apple-touch-icon" sizes="16x16" href="/images/favicon/shotgun-icon-16x16.png">

<meta name="msapplication-TileColor" content="#000000">
<meta name="msapplication-TileImage" content="/images/favicon/shotgun-icon-310x310.png">

    <link href="/stylesheets/minified/css_reset_3c48f8a065c41445dc685ee1c200fa0c.css" media="all" rel="Stylesheet" type="text/css" />
    <link href="/javascripts/ext/resources/css/ext-all.css?1589561892" media="all" rel="stylesheet" type="text/css" />
    <link href="/stylesheets/minified/login_1a4923c3683989206b2ce2d979fb65e7.css" media="all" rel="Stylesheet" type="text/css" />

    <script>
        var SG = {
            globals: {
                preferences: {}
            },
            Widget: {
                Base: function() {}
            }
        };
    </script>
    <script src="/page/i18n_data?locale=en&build=f1298f3"></script>

    <script src="/javascripts/minified/ext_4d1234604a5afdda966e66ca84f3960b.js?1589562510" type="text/javascript"></script>
<script src="/javascripts/minified/login_1efce95bb622b9f9c78cc259cc6b234c.js?1589562511" type="text/javascript"></script>
    <script src="/dist/es5/chunk.b4fbfba5af059bd74ad6.js"></script><script src="/dist/es5/chunk.14422cdc09a8315f20b8.js"></script><script src="/dist/es5/login.0c20cb3a6ae8f4c7bb58.js"></script>
</head>
<body class="sg_reset_body login_page ">
    <script type="text/javascript">
window.preprocesses= []
</script>
<script src="/javascripts/util/esdetect.js?f1298f3"></script>
<script>
    Ext.onReady(function () {
        _setup_globals();
        _setup_login();
        _setup_analytics();
    });

    function _setup_globals() {

        SG.globals = {
            theme: 'default',
            shotgun_version: 'v8.12.0.4393 (build f1298f3)',
            shotgun_version_branch: '',
            shotgun_build: 'f1298f3',
            hostname: 'studiodashboard.shotgunstudio.com',
            preferences: {
                enable_usage_analytics: true,
                using_user_invite_link: true
            },
            current_user: {
                // FIXME:
                // This should probably be:
                //     id: Number('') || undefined
                // But we'll keep legacy behavior of an empty String...
                id: ''
            },
            saml_claims_renew_iframe_embedding_disabled: false
        };
    }

    function _setup_login() {

        // Internationalization (i18n)
        SG.init_i18n('en', {"en":{"translation":{"components":{"login":{"back_to_login":"Back to login","login_label":"Login","password_label":"Password","sign_in_button":"Sign in","signing_in_button":"Signing in...","forgot_login_password":"Forgot login or password?","forgot_password_title":"Forgot your password?","forgot_password_message":"Enter your login or your email address below and we'll email you password reset instructions.","login_email_label":"Login/Email Address","password_reset_button":"Request password reset","forgot_login_title":"Forgot your login?","forgot_login":"Forgot your login?","forgot_login_message":"Enter your email address below and we'll send you your login information.","email_label":"Email","request_login_button":"Request login","browser_old_message":"Your browser is older than the current recommended version.","browser_not_supported_message":"Your browser is not supported.  You can proceed, but some of Shotgun's features will not function correctly.","learn_more":"Learn more here","back_to_2fa":"Back to Two-Factor Authentication","forgot_password_done_email_sent":"If you\u2019ve entered a valid email address or login, a password reset email has been sent to you.","forgot_password_done_email_click":"Click on the link in the email to reset your password.","forgot_login_done_emailed":"Your login information has been emailed to you.","two_fa_message":"Enter the code generated by the Google Authenticator or Duo Mobile app.","two_fa_enter_code_label":"Enter code","two_fa_verify_button":"Verify","two_fa_use_code":"Use a backup code","two_fa_enter_code":"Enter one of your backup codes.","two_fa_get_help":"Get help","two_fa_use_google_app":"Use the Google app","get_help_title":"Get Help","get_help_message":"Click the button below to request help from your Shotgun Admin with logging in to your account.","get_help_button":"Request admin help","get_help_done_message":"Your request has been sent to your Shotgun Admin.","saml_login_message":"This Shotgun Site uses your organization's username and password. Sign in to enter your credentials.","saml_sign_in_button":"Sign in","autodesk_identity_login_message":"This Shotgun Site uses Autodesk Identity. Sign in to enter your credentials.","autodesk_identity_sign_in_button":"Sign in","autodesk_identity_link_message":"A matching Autodesk Identity account cannot be found on this Shotgun site. ","autodesk_identity_link_message_2":"Please enter your old Shotgun account credentials to complete the account link.","autodesk_identity_select_message":"Please select the account you wish to sign in with.","merge_login_message":"Your account is currently being merged with your old account. This can take some time.","merge_estimated":"(estimated)","merge_contact_url":"Please {{- markup_start}}contact Shotgun support{{- markup_end}} if you have questions.","your_account_title":"Link your account","no_match_text":"Your Shotgun account is now linked to your Single Sign-On provider.{{- markup_line_break}}Do you already have a Shotgun account on this site? We can link your previous account so you can pick up where you left off.","already_have_option":"Yes, I already have an account on {{site}}.","my_first_option":"No, this is my first account on {{site}}.","find_account_button":"Find account","account_single_text":"We found the following account that seems to be yours. We'll link this account to your SSO account.","account_multi_text":"We found the following accounts that seem to be yours. Select one of the accounts and we'll link it to your SSO account.","account_hint":"By linking your account, you'll preserve your settings and preferences and continue to receive notifications about the things you're working on.","dont_want":"I don't want to link an account","link_account_button":"Link account","password_text":"Please enter the login and password for the Shotgun account you'd like to link to your SSO account","no_account":"No Shotgun account?","account_select_title_morning":"Good Morning,{{- markup_line_break}}{{first_name}}","account_select_title_afternoon":"Good Afternoon,{{- markup_line_break}}{{first_name}}","account_select_title_evening":"Good Evening,{{- markup_line_break}}{{first_name}}","link_another_account":"Link with a different account","select_linked_account":"Sign in with a different account"}},"moment":{"floating":{"yesterday_lowercase":"yesterday","today_lowercase":"today","tomorrow_lowercase":"tomorrow","yesterday":"Yesterday","today":"Today","tomorrow":"Tomorrow"},"social":{"at":"{{formatted_social_date}} at {{formatted_social_time}}","on":"on {{formatted_social_date_time}}"},"inbox":{"at":"{{formatted_inbox_date}} at {{formatted_inbox_time}}"},"calendar":{"friendly_day_number":"{{floating_today}} {{formatted_month_day}}"},"valid_option":{"date":{"1":"may 3","2":"tomorrow","3":"2008-m-d","4":"{{- day_month_structure}}/07' or '{{- day_month_structure}}","day_month":"d/m","month_day":"m/d"},"date_time":{"1":"may 3 12pm","2":"tomorrow 9:30","3":"2008-m-d 7:30 AM","4":"{{- day_month_structure}}/07 13:00' or '{{- day_month_structure}} 7 am"}},"filters":{"date_time_delimiter":" ","date":[],"time":[],"zone":[]},"formats":{"sg_floating":"YYYY/MM/DD","sg_parse":"YYYY/MM/DD HH:mm a","sg_gantt_year_for_math":"Y","sg_gantt_month_for_math":"n","sg_gantt_dotw_for_math":"w","sg_24_hour_time":"H:i","sg_12_hour_no_pad":"g:ia","sg_12_hour_with_pad":"h:ia","sg_add_note_to_selected":"- F s","sg_manage_shares_popover":"Y-m-d G:i:00 UTC","sg_dependency_violation":"l, M j","sg_social_longform_weekday_only":"l","sg_social_month_day":"F j","sg_social_day_month":"j F","sg_social_month_day_full_year":"F j Y","sg_social_day_month_full_year":"j F Y","sg_calendar_month_label":"F Y","sg_full_year":"Y","sg_short":"M d","sg_short_with_year":"M d y","sg_short_year":"y","sg_inbox_month_day":"M j","sg_inbox_day_month":"j M","sg_inbox_month_day_full_year":"M j Y","sg_inbox_day_month_full_year":"j M Y","sg_gantt_segment_drag":"D, M j","sg_gantt_bar_drag_md":"M j","sg_gant_bar_drag_mdy":"M j/y","sg_gantt_bar_drag_d":"j","sg_day_of_the_week":"w","sg_numeric_month_no_pad":"n","sg_full_month_year":"F Y","sg_full_month_short_year":"M y","sg_numeric_month_with_pad":"d","sg_gantt_day_no_pad_month_abbr":"j/M","sg_gantt_action_menu_items":"D, F d","sg_gantt_render_tooltip":"D, M j y","sg_gantt_render_rule_tooltip":"l, F j","sg_work_week_calendar_month_year":"M Y","sg_pivot_tooltip":"D, M j y","sg_client_timestamp":"M d, Y g:i A","sg_media_new_playlist":"n/j/Y","sg_media_unique_time":"g:i","sg_media_unique_meridiem":"a","sg_planning_within_week":"M j","sg_planning_within_month":"M Y","sg_task_same_week":"D","sg_task_same_year":"M j","sg_task_alt_year":"M j, Y","sg_week_history":"M j, Y","sg_month_with_pad":"m","sg_month_abbr":"M","sg_numeric_month_day_no_pad":"j","sg_timeline_heard_major_month":"F Y","sg_timeline_heard_major_month_weeks":"M y","sg_timeline_label_day":"D j","sg_timeline_week_long":"j/M","sg_timeline_range_menu_date_same":"M j","sg_timeline_range_menu_date":"M j, Y","sg_timesline_app_range_menu":"{{low_date}} - {{high_date}}","sg_calendar_today":"Y m d","sg_calendar_today_dash":"Y-m-d","sg_calendar_firstday":"Y m 1","sg_calendar_lastday":"Y m t","sg_calendar_constants":"Y m j","sg_iso_week_number":"W","sg_calendar_events_greater_70d":"M j ( D )","sg_calendar_events_greater_40d":"M j","sg_calendar_numeric_date_no_pad":"Y n j","sg_fallback_date_fields_code":"D, M j y","sg_manage_shares_popover_release_date":"j M Y","mjs_2fa_backup_codes_created_at":"Y/M/D","mjs_calendar_header":"MMMM YYYY","ruby":{"grouping_handler":{"date":"%B %d, %Y","month":"%B %Y","year":"%Y","qtr":"Q{{qtr_num}} %Y","exact_date":"%b %d %y","exact_datetime":"%Y-%m-%d %H:%M:%S","between_dates":"{{from_date}} to {{to_date}}"},"note_subject":{"date_format":"%B {{day}}","default_subject":"{{title}} - {{date}}"}}},"preferences":{"dayname_monthname_day_longyear":{"format":"l, F j, Y","filter":"dddd, MMMM D, YYYY"},"shortdayname_shortmonthname_day_shortyear":{"format":"D, M j y","filter":"ddd, MMM D YY"},"longmonthname_day_longyear":{"format":"F j, Y","filter":"MMMM D, YYYY"},"shortmonthname_day_longyear":{"format":"M j, Y","filter":"MMM D, YYYY"},"shortmonthname_day":{"format":"M j","filter":"MMM D"},"padday_shortmonthname_shortyear":{"format":"d M y","filter":"DD MMM YYYY"},"longyear_padmonth_padday_dashed":{"format":"Y-m-d","filter":"YYYY-MM-DD"},"longyear_padmonth_padday_slashed":{"format":"Y/m/d","filter":"YYYY/MM/DD"},"short_dmy_mdy_slashed":{"day_month":{"format":"j/n/y","filter":"D/M/YY"},"month_day":{"format":"n/j/y","filter":"M/D/YY"}},"short_pad_dmy_mdy_slashed":{"day_month":{"format":"d/m/y","filter":"DD/MM/YY"},"month_day":{"format":"m/d/y","filter":"MM/DD/YY"}},"padmonth_padday_slashed":{"format":"m/d","filter":"MM/DD"}},"relative_time":{"display":"{{number}} {{duration}}","duration":{"M":{"singular":"month","plural":"months"},"d":{"short":"d","singular":"day","plural":"days"},"m":{"short":"m","singular":"minute","plural":"minutes"},"s":{"singular":"second","plural":"seconds"},"y":{"singular":"year","plural":"years"},"h":{"short":"h","singular":"hr","plural":"hrs"},"w":{"short":"w","singular":"week","plural":"weeks"}}},"email":{"strf_general_value_date":"%a %b %d, %y","strf_formatted_event_time":"%a %b %-d, %Y at %I:%M%P (%Z)","strf_general_value_datetime":"%a, %b %d %y, %I:%M:%S%P %Z","strf_formatted_when":"%a %b %-d, %Y, %I:%M%P (%Z)"}}}}});

        SG.login = new SG.Login(sg_extend(null || {}, {
                        // Flash messages:
                                                                        
            
            
            

            

            // Browser flags:
                    }));
    }

    function _setup_analytics() {
        SG.analytics = new SG.util.Analytics({
            amplitude_api_key: 'a9895d870c5f3abe4aad5d8aabeff2ea',
            site_id: '45457',
            site_name: 'com_shotgunstudio_studiodashboard'
        });

        SG.analytics.ready(function () {
            var action = (SG.login.flash_notice || '').search('logged out') === -1 ? 'Login' : 'Logout';

            // Track Page:
            var page_name = action + ' Page';
            var page_config = {
                // - normalize flash messages to single property:
                flash_messages: ['notice', 'warning', 'error'].filter(function (type) {
                    return !!SG.login['flash_' + type];
                }).map(function (type) {
                    return type.toUpperCase() + ': ' + SG.login['flash_' + type];
                })
            };

            // Track Logout?
            if (action === 'Logout') {
                SG.analytics.track('App', 'Logged Out', sg_extend({
                    // NOTE:
                    // manually setting `source`, as `/user/login` doesn't load `SG.Page` or `SG.globals.page`,
                    // which we usually use to infer page data across the rest of SG
                    source: page_name
                }, page_config));
            }

            this.track_page('App', page_name, page_config);
        });
    }
</script>

    <div id="shotgun_version" class="build_no">
        v8.12.0.4393 (build f1298f3)
    </div>

    <script>
        // Internationalization (i18n)
        SG.init_i18n('en', SG.globals.i18n_data);
    </script>
</body>
</html>
1 Like

Ah, that returned HTML is actually the login page, so the connection isn’t authenticated and it’s clumsily trying to prompt you to log in. I’ll check with the engineers to see what the right format would be here to make this work in REST.

2 Likes

To confirm…this url

https://######.shotgunstudio.com/thumbnail/full/CustomNonProjectEntity08/56 does in fact take me to the full res thumbnail. So if you take that url and put it into the address bar and hit enter, it turns into something like https://sg-media-usor-01.s3-accelerate.amazonaws.com/… which is the url i need to directly display the high res image.

1 Like

Hey @JokerMartini - this should give you what you need using Python and requests. Not sure if the formatting will be right here.

import requests
import json
import os

# These are from my env. vars - change as you see fit
BASE_URL = "https://bwillenbringstab1.stab.shotguncloud.com"
LOGIN = os.environ["ADMIN_USER"]		
PWD = os.environ["ADMIN_PWD"]

# Method that allows us to obtain a token based on HumanUser credentials
def get_token(username, password):
	auth_url = "%s/api/v1/auth/access_token" % BASE_URL
    # Set up your post payload
	data = {
		"username": username,
		"password": password,
        "grant_type": "password"
	}
    # And your headers
	headers = {'content-type':'application/x-www-form-urlencoded'}
	response = requests.post(auth_url, data=data, headers=headers)
    # Return the token 
	return "Bearer %s" % str(response.json().get("access_token"))

# Method that just prints the values of the given fields
def get_entity(entity_type, id, fields=['*']):
    # Convert the fields into a querystring
    querystring = "?fields=%s" % ",".join(fields)
    # Here is basic GET endpoint for a single entity type of 'Asset' with a known id, and a comma-separated list of fields
    endpoint = "%s/api/v1/entity/%s/%s%s" %(BASE_URL, entity_type, id, querystring)
    # Furnish the headers containing the access token
    headers = {
        "Authorization": get_token(LOGIN, PWD),
        "Content-type": "application/json"
    }
    # GET the REST API endpoint using requests (note: not all endpoints use the GET method)
    r = requests.get(endpoint, headers=headers)

    # Print the thumbnail, which is nested in the response's data.attributes 
    print r.json()["data"]["attributes"]
    # And this ^^ prints something like...
    # https://sg-media-sb-usor-01.s3-accelerate.amazonaws.com/499a4b4678f52f06360b26de689b4f59da270265/27a06214d88a1da17c333b9629ad927017dbe288/13_t.jpg?response-content-disposition=filename%3D%2213_t.jpg%22&x-amz-meta-user-id=42&x-amz-meta-user-type=HumanUser&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=ASIAZEK2H4X5AXMEJXQW%2F20200520%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20200520T133845Z&X-Amz-Expires=900&X-Amz-SignedHeaders=host&X-Amz-Security-Token=FwoGZXIvYXdzEM%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FwEaDGrGSI5Wh8ruJi16nCKvAVbaBbVXjBUD9SH%2F%2FMk6F1M4zJL8FG4XST3E2wWhxkey9Oq0c4Bon%2BWdCiuhXK4h%2FW8V6VbdinnA44ZCxUypeZZkZx3FXqvjs6ML%2Bc%2FSHEZnVIFEN%2FsMq7RC6fhrCnb8rI8UwLA2F0yZD7uCm6%2BTHOzR5Ypp%2BlxyNi797bBoIKk1nehLPjWfDH7HrusHgNkk29axdWsHupgHWbjD0%2B1p2Z%2FnhLLbnfw04yq%2BsdhUvS8omtaU9gUyLWpbVQ%2FtuksQTyjwJ2cT7cxRrnUcBFU4JrHRDk0H524oNPvUrZQfrxi5niQ2cw%3D%3D&X-Amz-Signature=e74885fb3163e47784c4e7fd072c865a28b427cb8cff98dac0eb56ff1bf62713

if __name__ == "__main__":
    get_entity("Asset", 870, ["image"])
3 Likes

This still appears to be the low res image. Not the original raw full res image.

1 Like

# Downloads the thumbnail associated to the given entity.
# @param entity_type [String] type of the entity the media is attached to
# @param record_id [number] id of the entity the media is attached to
# @param size [String] 'original' or 'thumbnail'.
# @param local_file_path [String] local path where to download the file
def download_thumbnail(entity_type, record_id, size, local_file_path)
  headers = setup_auth_headers
  headers['Accept'] = 'application/json'
  url = "#{@host}/api/v1/entity/#{entity_type}/#{record_id}/image?alt=#{size}"
  begin
    resp = download_thumbnail_internal(url, headers)
    return false unless resp
    File.binwrite(local_file_path, resp.body)
    return true
  rescue RestClient::ExceptionWithResponse => err
    debug "Could not download thumbnail:  #{err.response.code}"
    debug "Could not download thumbnail:  #{err.response.body}"
  end
  false
end
  def download_thumbnail_internal(url, headers)
    resp = RestClient::Request.execute(method: :get, url:url, headers: headers , max_redirects: 0)
  rescue RestClient::ExceptionWithResponse => err
    if err.response.code == 302
      resp = RestClient::Request.execute(method: :get, url:err.response.headers[:location])
      File.binwrite(local_file_path, resp.body)
      return true
    end
    resp
  end
1 Like

What is happening here? Is this download the file or just giving me the return path to it’s location on the s3 server?

1 Like

ps i like the image :slight_smile:

1 Like

I sent you a DM (inbox) that contains some useful information that we can use to quickly test. Once we resolve it and we can post the final solution without sensitive information here on the forums for others to benefit from :slight_smile:

1 Like

Hi JokerMartini!

(For reference to others, the code snippet above was pulled from the sample file posted here:
https://developer.shotgunsoftware.com/rest-api/#shotgun-rest-api-Uploading-and-Downloading-Files (Code sample section, python example))

If I understand correctly your question, I beleive the code you are looking for is here:

More specifically, line 120 shows the URL to use:
url = “%s/api/v1/entity/%s/%s/image?alt=%s”%(self.host, entity_type, record_id, size)

The “size” parameter can be either ‘original’ or ‘thumbnail’. It looks like you want to use ‘original’.

As you can see at line 125, this will return the actual content, not the signed S3 url.

I hope this helps!

1 Like

That is what i used however it throws up errors when using the rest api. I’ve send a direct message to Brandon that shows the issue. I can forward it to you if you’d like.

1 Like

yes, please!

2 Likes

Hey Stephane,
I was using your python module for uploading files to shotgun using the rest api. There is a bug i commented on the file.

Secondly, when i upload an mp4 using the module, it seems to always display the name ‘string’ instead of the name of the file. Is there a way to fix that?

image

2 Likes

Nevermind i found where it’s being set :slight_smile:

Should probably change it to be the filename by default. great work on the module. Huge help for uploading.

complete_upload_data = {
“upload_info”: complete_upload_info,
“upload_data”: {
“display_name”: “string”
}
}

1 Like