How to enable swagger UI in AWS - amazon-web-services

I created the serverless application using .Net core and hosted in AWS. I am able to create swagger.json by publishing API documentation under API gateway.
I am looking for the documentation to create swagger UI for those APIs.
Is any possibility to view the swagger UI in AWS itself.

I do not think AWS built a swagger UI in one of their services. At least, I am not aware of it.
However, it is possible to easily create a swagger visualization using S3.
There is an article on Medium which explains this well. [1]
Basically, what you need to script is:
Creation of an S3 bucket with static website hosting
Downloading the static swagger UI resources from GitHub
Syncing the resources to the S3 bucket
Downloading the swagger.json from API Gateway [2]
Uploading the swagger.json to S3
Modify index.html to point at your swagger.json
These steps are laid out in detail in the Medium article. [1]
References
[1] https://medium.com/nirman-tech-blog/swagger-ui-for-aws-api-gateway-endpoints-a667f25f5a4b
[2] https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-export-api.html

You can easily host self-contained swagger-UI web site in S3.
Here is an example: https://iris-fhir-server.s3.amazonaws.com/swagger-ui.html
Github: https://github.com/intersystems-community/Swagger-IRIS-FHIR
It's essentially your OpenAPI yaml or json files plus single HTML page like:
<!-- HTML for static distribution bundle build -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Swagger UI</title>
<link rel="stylesheet" type="text/css" href="https://unpkg.com/swagger-ui-dist#3/swagger-ui.css" >
<style>
html
{
box-sizing: border-box;
overflow: -moz-scrollbars-vertical;
overflow-y: scroll;
}
*,
*:before,
*:after
{
box-sizing: inherit;
}
body
{
margin:0;
background: #fafafa;
}
.errors-wrapper {
display: none !IMPORTANT;
}
</style>
</head>
<body>
<div id="swagger-ui"></div>
<script src="https://unpkg.com/swagger-ui-dist#3/swagger-ui-bundle.js"> </script>
<script src="https://unpkg.com/swagger-ui-dist#3/swagger-ui-standalone-preset.js"> </script> <script>
window.onload = function() {
// Begin Swagger UI call region
const ui = SwaggerUIBundle({
"dom_id": "#swagger-ui",
deepLinking: true,
presets: [
SwaggerUIBundle.presets.apis,
SwaggerUIStandalonePreset
],
plugins: [
SwaggerUIBundle.plugins.DownloadUrl
],
layout: "StandaloneLayout",
validatorUrl: "https://validator.swagger.io/validator",
//url: "https://iris-fhir-server.s3.amazonaws.com/openapi/Patient.yml",
urls: [
{url: "https://iris-fhir-server.s3.amazonaws.com/openapi/Organization.yml", name: "Organization"},
{url: "https://iris-fhir-server.s3.amazonaws.com/openapi/Patient.yml", name: "Patient"},
{url: "https://iris-fhir-server.s3.amazonaws.com/openapi/Practitioner.yml", name: "Practitioner"},
{url: "https://iris-fhir-server.s3.amazonaws.com/openapi/Condition.yml", name: "Condition"},
{url: "https://iris-fhir-server.s3.amazonaws.com/openapi/Medication.yml", name: "Medication"},
{url: "https://iris-fhir-server.s3.amazonaws.com/openapi/Observation.yml", name: "Observation"}
],
"urls.primaryName": "Patient"
})
window.ui = ui
}
</script>
</body>
</html>

Related

Power Bi and WebBrowser control

It is possible to render a power bi report in a windows form web browser control? I created an html file and added to navigate method but is not working. Also I added the html content to the documenttext property and is not working.
I'm using the embed for customer.. approach but I only get a blank page. This is the code that I pass to the webbrowser control. Do you have a sample using the windows forms project?
<!DOCTYPE html>
<html lang='en' xmlns='http://www.w3.org/1999/xhtml'>
<head>
<meta charset='utf-8' />
<title></title>
<script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js' referrerpolicy='no-referrer'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/powerbi-client/2.19.1/powerbi.min.js' integrity='sha512-JHwXCdcrWLbZo78KFRzEdGcFJX1DRR+gj/ufcoAVWNRrXCxUWj2W2Hxnw61nFfzfWAdWchR9FQcOFjCNcSJmbA==' crossorigin='anonymous' referrerpolicy='no-referrer'></script>
</head>
<body>
<div id='embedContainer'></div>
<script type="text/javascript">
const reportContainer = $('#embedContainer')[0];
const accessToken = 'token.....';
const embedUrl = 'https://xxx.powerbi.com/reportEmbed?reportId=0b0fe232.....';
const embedReportId = '0b0fe232.....';
const tokenExpiry = '5/20/2022 5:42:13 PM';
const models = window['powerbi-client'].models;
const config = {
type: 'report',
tokenType: models.TokenType.Embed,
accessToken: accessToken,
embedUrl: embedUrl,
id: embedReportId,
permissions: models.Permissions.All,
settings:
{
filterPaneEnabled: true,
navContentPaneEnabled: true
}
};
const report = powerbi.embed(reportContainer, config);
</script>
</body>
</html>
Thanks,
Ev
Yes. There are a number of approaches you can consider.
Power BI Secure Embedding just uses an IFrame and the desktop user will need to authenticate to Power BI. Minimally generate the embedding link from Power BI
and embed it in an a static HTML page like this:
<html>
<iframe title="Some Report"
style="position: absolute; height: 100%; width: 100%; border: none"
src="https://xxx.powerbi.com/reportEmbed?reportId=d12ecc27-a855-4b27-9..."
frameborder="0"
allowFullScreen="true">
</iframe>
</html>
Or you can build and register full web app to do embedding using either the Embed For Your Customers, or the Embed For Your Organization workflow. This adds a javascript API to control and interact with the embedded reports from your hosting application.

COG on Google Cloud Storage - error using OpenLayers without NodeJS

I'm playing with OpenLayers to display COG files uploaded on GCS.
Using the NodeJS, an index.html and a main.js files, then building with Parcel (or others), everything works fine.
When I tried to skip using NodeJS, coding an HTML files with the CDN imports, and the inline JavaScript, it looks like OpenLayers is not able to retrieve all the needed dependencies. In particular in the network request/response, I have:
Request URL: https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io#master/en/v6.14.1/build/231.ol.js
Request Method: GET
Status Code: 403
Remote Address: 151.101.241.229:443
Referrer Policy: strict-origin-when-cross-origin
and if I try to hit directly the URL in the Browser:
https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io#master/en/v6.14.1/build/231.ol.js
I got:
Package size exceeded the configured limit of 50 MB. Try https://github.com/openlayers/openlayers.github.io/tree/master/en/v6.14.1/build/231.ol.js instead.
Why?
Below the content of the HTML file I stored on GCS (layer styling omitted),
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>COG on Google Cloud Storage</title>
<script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io#master/en/v6.14.0/build/ol.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io#master/en/v6.14.0/css/ol.css">
<style>
html, body {
margin: 0;
height: 100%;
}
#map {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
}
</style>
</head>
<body>
<div id="map"></div>
<script type="text/javascript">
var cogSource = new ol.source.GeoTIFF (
{
normalize: true,
sources: [
{
url: 'https://storage.googleapis.com/fao-gismgr-cache/TEST/L1_AETI_21.tif',
min: -9999,
max: 16000
}
],
transition: 0
}
);
var cogLayer = new ol.layer.WebGLTile (
{
source: cogSource
}
);
var cogView = new ol.View (
{
projection: 'EPSG:4326',
minZoom: 0,
maxZoom: 12,
center: [0,0],
zoom: 4
}
);
var map = new ol.Map({
target: 'map',
maxTilesLoading: 32,
layers: [cogLayer],
view: cogView
});
</script>
</body>
</html>
The COG and HTML file are on a public GCS bucket.
To test, I use Chrome with web-security disabled (CORS policies)
open -na Google\ Chrome --args --user-data-dir=/tmp/temporary-chrome-profile-dir --disable-web-security --disable-site-isolation-trials
Could you help me?
Thanks in advance,
Davide
Thanks #Mike, I was having the same problem and tried your solution both with local and remote files and it worked without any problem.
<script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io#master/en/v6.12.0/build/ol.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io#master/en/v6.12.0/css/ol.css">

How can I embed an Autodesk Forge Viewer to a Flask App without CORS errors?

I followed the Developer's Guide (step 1-3) to create an html file to view my BIM model - this worked fine.
But if I put the same code into a flask app I am not able to view the BIM model. I looked at the requests and found a couple of CORS errors while loading the document with Autodesk.Viewing.Document.load:
If I hover over CORS error I got a small popup telling me: "Cross origin resource sharing error: HeaderDisallowedByPreflightResponse".
I tried to change the callback url of my forge app to http://localhost:5001 and http://localhost:5001/* but this had no impact.
How can I embed an Autodesk Forge Viewer to a Flask App without CORS errors?
Why are there CORS errors on localhost but not on file:///.../index.html?
update:
Here is my html file - which works (I removed secrets here). I basically just put the same code into a flask app...
<!DOCTYPE html>
<html lang="en">
<head>
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=no"/>
<meta charset="utf-8">
<title>Axpo BIM Viewer</title>
<link rel="stylesheet" href="https://developer.api.autodesk.com/modelderivative/v2/viewers/7.*/style.min.css"
type="text/css">
<script src="https://developer.api.autodesk.com/modelderivative/v2/viewers/7.*/viewer3D.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.js"></script>
<style>
body {
margin: 0;
}
#forgeViewer {
width: 100%;
height: 800px;
margin: 0;
background-color: #F0F8FF;
}
#forgeViewer > div {
height: 800px !important;
}
</style>
<script>
$(() => {
let client_id = '__client_id__'
let client_secret = '__client_secret__'
let documentId = 'urn:__documentId__'
let htmlDiv = document.getElementById('forgeViewer');
let viewer = new Autodesk.Viewing.GuiViewer3D(htmlDiv);
get_an_account(client_id, client_secret).then(function (response) {
initialize_viewer(viewer, response.access_token)
load_document(viewer, documentId)
});
});
async function get_an_account(client_id, client_secret) {
var request = {
"url": 'https://developer.api.autodesk.com/authentication/v1/authenticate',
"method": "POST",
"timeout": 0,
"headers": {
'Content-Type': 'application/x-www-form-urlencoded'
},
"data": {
client_id: client_id,
client_secret: client_secret,
grant_type: 'client_credentials',
scope: 'code:all data:write data:read bucket:create bucket:delete bucket:read'
}
};
return $.ajax(request);
}
function initialize_viewer(viewer, token) {
var options = {
env: 'AutodeskProduction2',
api: 'streamingV2', // for models uploaded to EMEA change this option to 'streamingV2_EU'
getAccessToken: function (onTokenReady) {
var timeInSeconds = 3600; // Use value provided by Forge Authentication (OAuth) API
onTokenReady(token, timeInSeconds);
}
};
Autodesk.Viewing.Initializer(options, () => {
var startedCode = viewer.start();
if (startedCode > 0) {
console.error('Failed to create a Viewer: WebGL not supported.');
return;
}
console.log('Initialization complete, loading a model next...');
});
}
function load_document(viewer, documentId) {
Autodesk.Viewing.Document.load(documentId, (viewerDocument) => {
var defaultModel = viewerDocument.getRoot().getDefaultGeometry();
viewer.loadDocumentNode(viewerDocument, defaultModel);
}, () => {
console.error('Failed fetching Forge manifest');
});
}
</script>
</head>
<body>
<div id="forgeViewer"></div>
</body>
</html>
I could not reproduce the issue, however, one thing that will be causing problems is that you're not waiting for initialize_viewer() to finish before trying to load a document. Looks like when using the file:// protocol, you don't run into problems with that though.
I turned that function into a Promise so that we can await it.
Also, it's better to keep the client secret on the server side, so I added that to the code too. You'll just have to update the variables in server.py
This solution worked fine for me. Maybe your Flask app has some different settings that cause the issue?
I had index.html in the templates folder:
<!DOCTYPE html>
<html lang="en">
<head>
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=no" />
<meta charset="utf-8" />
<title>Axpo BIM Viewer</title>
<link rel="stylesheet" href="https://developer.api.autodesk.com/modelderivative/v2/viewers/7.*/style.min.css" type="text/css" />
<script src="https://developer.api.autodesk.com/modelderivative/v2/viewers/7.*/viewer3D.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<style>
body {
margin: 0;
}
#forgeViewer {
width: 100%;
height: 800px;
margin: 0;
background-color: #f0f8ff;
}
#forgeViewer>div {
height: 800px !important;
}
</style>
<script>
$(async() => {
let documentId = "urn:{{ documentId }}";
let htmlDiv = document.getElementById("forgeViewer");
let viewer = new Autodesk.Viewing.GuiViewer3D(htmlDiv);
await initialize_viewer(viewer);
load_document(viewer, documentId);
});
async function get_access_token(onTokenReady) {
var request = {
url: "/access_token",
method: "GET",
};
let res = await $.ajax(request);
console.log(res);
onTokenReady(res.access_token, res.expires_in);
}
async function initialize_viewer(viewer) {
return new Promise(resolve => {
var options = {
env: "AutodeskProduction2",
api: "streamingV2", // for models uploaded to EMEA change this option to 'streamingV2_EU'
getAccessToken: get_access_token,
};
Autodesk.Viewing.Initializer(options, () => {
var startedCode = viewer.start();
if (startedCode > 0) {
console.error("Failed to create a Viewer: WebGL not supported.");
return;
}
console.log("Initialization complete, loading a model next...");
resolve();
});
})
}
function load_document(viewer, documentId) {
console.log("Loading document");
Autodesk.Viewing.Document.load(
documentId,
(viewerDocument) => {
var defaultModel = viewerDocument.getRoot().getDefaultGeometry();
viewer.loadDocumentNode(viewerDocument, defaultModel);
},
() => {
console.error("Failed fetching Forge manifest");
}
);
}
</script>
</head>
<body>
<div id="forgeViewer"></div>
</body>
</html>
server.py
from flask import Flask, render_template
import requests
app = Flask(__name__)
# Update variable values
document_id=""
client_id=""
client_secret=""
#app.route("/")
def run():
return render_template('index.html', documentId=document_id)
#app.route("/access_token")
def get_access_token():
headers = {"Content-Type": "application/x-www-form-urlencoded"}
body = (
f"client_id={client_id}"
f"&client_secret={client_secret}"
"&grant_type=client_credentials"
"&scope=viewables:read"
)
print(body)
res = requests.post("https://developer.api.autodesk.com/authentication/v1/authenticate", data=body, headers=headers)
data = res.json()
return data
"Why are there CORS errors on localhost but not on file:///.../index.html?"
I guess the browser has different security concerns for the different protocols. The Viewer does not support the file:// protocol (only http:// / https://) and with some models you'll run into issues because of that - e.g. like this:

Facebook's Checkbox plugin remains hidden no matter what I try

I'm having trouble getting the Messenger Checkbox plugin to work: the Facebook script loads fine, it parses the page well (I can see this with the debug version of the SDK), but the checkbox remains in "hidden" status.
This is an HTML sample of my page:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>TestCheckboxMessenger</title>
<base href="/" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" type="image/x-icon" href="favicon.ico" />
</head>
<body>
<!-- Load Facebook SDK for JavaScript -->
<div id="fb-root"></div>
<script>
window.fbAsyncInit = function () {
FB.init({
appId: "[my-app-id]",
autoLogAppEvents: true,
xfbml: true,
version: "v10.0",
});
FB.Event.subscribe("messenger_checkbox", function (e) {
if (e.event == "rendered") {
console.log("Plugin was rendered");
} else if (e.event == "checkbox") {
var checkboxState = e.state;
console.log("Checkbox state: " + checkboxState);
} else if (e.event == "not_you") {
console.log("User clicked 'not you'");
} else if (e.event == "hidden") {
console.log("Plugin was hidden");
}
});
};
</script>
<script async defer crossorigin="anonymous" src="https://connect.facebook.net/fr_FR/sdk/debug.js"
></script>
<div
class="fb-messenger-checkbox"
origin="https://[my-domain-name]/"
page_id="[my-page-id]"
messenger_app_id="[my-app-id]"
user_ref="[some-random-id]"
size="medium"
skin="light"
center_align="true"
></div>
<app-root></app-root>
</body>
</html>
I have carefully read the facebook documentation and the solutions proposed on StackOverflow, but the checkbox does not appear. I have taken into account the following points:
My page is served on HTTPS with a domain name that is whitelisted in my page options
The user_ref is a randomly generated id that is new on every page refresh
My app is in what was called "development mode" so I have Standard access to pages_messaging and I have admin role on the app (and I am connected to my account)
My Messenger webhook is live and working
As strange as it may seem, the conversation plugin works fine.
What conversation plugin looks like
Is there a method to debug the checkbox status? To know why it is hidden? Because I have no error message in the Chrome console and all this is very frustrating :)
Ok so, acccording to this Facebook Update, the checkbox plugin and some other features including optin mechanics, media messages, etc. have been deactivated in Europe and some other countries because of GDPR.
Facebook planned to restore them by Q1 2021, but now they are moving the timeline towards Q2 2021.
I don't understand why they don't put a warning message on the docs about these features... :(

Facebook tutorial projects don't work for me, return "undefined"

I'm new to developing for Facebook. I'm actually writing an app for a university course.
I followed the tutorials on the developer website, and they originally worked like a charm. I used the example which produced a login with Facebook button, and another page which would retrieve information from the logged in user and display it on the page.
I left it for a couple of weeks to work on other commitments, now this code doesn't work. Whereas before it would list the profile picture, name, email etc. Now it just says undefined. The only thing I could put it down to was that I had been using something which had been depreciated, since I'd now switched over to the timeline for my Facebook account (however why would the original example I used still be the first set of tutorials on the developer website https://developers.facebook.com/docs/guides/web/).
I also went to the Open Graph page on the developer website, they have a tutorial there which just displays a picture of a cookie and then adds the app to your timeline (I'm sure you're all familiar with it). That doesn't work either! It just brings up a blank box which immediately vanishes (doesn't ask me to authorise anything) and doesn't add anything to my timeline.
I've tried looking at my app settings but I can't see anything odd.
Probably you are using some deprecated functions.
First thing to do is to make sure you have an application created on facebook, and that the site URL on the settings of the application is the site that you are writing your application (example: http://locahost/application_name). Also, take note of the application id (you can find all these settings on https://developers.facebook.com/apps/).
Now that you got this, here is working example for extracting information for your user (replace "YOUR_APP_ID" with your application ID:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<link rel="stylesheet" type="text/css" media="screen" href="styles/styles.css" />
<link rel="stylesheet" type="text/css" media="screen" href="styles/default.css" />
<script type="text/javascript" src="js/jquery-ui.min.1.8.js"></script>
<script type="text/javascript" src="js/jquery-1.7.1.min.js"></script>
<script type='text/javascript' src="js/jquery-ui.min.js"></script>
<script type='text/javascript' src="js/main.js"></script>
<script type='text/javascript' src='js/default.js'></script>
<script language="JavaScript">
function get_feed()
{
FB.api('/me', function(response) {
alert(response.name);
});
}
</script>
</head>
<body>
<div id="fb-root"></div>
<div id="login"></div>
<div id="test"></div>
<div id="stream"></div>
<script src="http://connect.facebook.net/en_US/all.js"></script>
<script>
FB.init({
appId : 'YOUR_APP_ID',
status : true, // check login status
cookie : true, // enable cookies
xfbml : true, // parse XFBML
oauth : true
});
FB.Event.subscribe('auth.authResponseChange', function(response) {
window.location.reload();
});
FB.getLoginStatus(function(response) {
if (response.status == "connected") {
// logged in and connected user, now get the facebook info
get_feed();
document.getElementById('login').innerHTML
='Logout fom Facebook<br/>';
} else {
document.getElementById('login').innerHTML
='<fb:login-button show-faces="true" width="200"'
+ ' max-rows="1" perms="user_about_me, user_likes, friends_likes, read_stream, publish_stream">'
+ '</fb:login-button>';
FB.XFBML.parse();
}
});
</script>
</body>
</html>
Hope it helps.