Bulk Import Request for FHIR - hl7-fhir

https://github.com/smart-on-fhir/bulk-import/blob/master/import.md
I used above link for reference and tried to run import using the following code
import requests
url = "https://<fhir-server-name>.azurehealthcareapis.com/$import"
payload = "{\r\n\t\"inputFormat\": \"application/fhir+ndjson\",\r\n\t\"inputSource\": \"https://localhost\",\r\n\t\"storageDetail\": { \"type\": \"https\" },\r\n\t\"input\": [\r\n\t{\r\n\t\t\"type\": \"Patient\",\r\n\t\t\"url\": \"https://localhost/patient_ndjson.ndjson\"\r\n\t}\r\n\t]\r\n}"
headers = {
'Accept': 'application/fhir+json',
'Prefer': 'respond-async',
'Content-Type': 'application/json',
'Authorization': 'Bearer <Auth Token>'
}
response = requests.request("POST", url, headers=headers, data = payload)
print(response.text.encode('utf8'))
i am receiving 400 Bad Request . i tried posting to both
url = "https://<fhir-server-name>.azurehealthcareapis.com/$import"
url = "https://<fhir-server-name>.azurehealthcareapis.com/Patient/$import"
I used apache for hosting the file and the file is accessible with both http and https.. Instead of importing it using http server, is there any way to directly point to my local ndjson file ?
patient_ndjson.ndjson contains
{"resourceType":"Patient","id":"8c76dfe7-2b94-497b-9837-8315b150ac0e","meta":{"versionId":"1","lastUpdated":"2020-04-27T11:08:10.611+00:00"},"active":true,"name":[{"use":"official","family":"p000001"}],"gender":"female","birthDate":"2020-04-27T11:00:00+05:30"}
{"resourceType":"Patient","id":"bfab05c7-d36a-4b5a-a0d6-6efb1da0fb3d","meta":{"versionId":"1","lastUpdated":"2020-04-27T11:34:43.83+00:00"},"active":true,"name":[{"use":"official","family":"p000001"}],"gender":"female","birthDate":"2020-04-27T11:00:00+05:30"}
{"resourceType":"Patient","id":"4c314eb1-6309-424b-affc-197fb0131cf6","meta":{"versionId":"1","lastUpdated":"2020-04-27T12:09:20.777+00:00"},"active":true,"name":[{"use":"official","family":"p000002"}],"gender":"female","birthDate":"2020-04-27T03:00:00+05:30"}
Can you please provide some sample request . it would be helpful.

$import is a draft spec and it is not supported (yet) on the Azure API for FHIR.

Related

Handling base64 string as application/pdf for a single endpoint on API Gateway

We have an API that has multiple different endpoints, as you'd expect. We have the requirement to add a new endpoint which will return an application/pdf along with the file data.
To do this, we return the following:
return {
statusCode: 200,
headers: {
'Content-Type': 'application/pdf',
'Content-disposition': `attachment; filename=${filename}.pdf`,
'Accept': 'application/pdf',
},
body: fileData,
isBase64Encoded: true,
};
The isBase64Encoded only works when a binary media type is set in the API Gateway. As detailed here:
https://medium.com/#ngchiwang/aws-api-gateway-lambda-return-binary-image-ba8faa660839
The issue we have is that by setting the binary media type to * / * (no spaces) on the API Gateway, this, in turn, affects all other endpoints on the API.
Example This breaks one endpoint on the OPTIONS cors check, returning an InternalServerErrorException without reason. This endpoint is just a GET with no data in the request.
Does this mean we need a separate API just for this one endpoint, or is there a way we can include this in the same APIG?
For further clarification, this is a POST that includes a small amount of JSON in the request: {"someValue":1234} and returns the above application/pdf content type.
I'm just tackling this issue and resolved it like this:
Send base 64 string just as normal json response and handle the pdf part on the client
const sendRes = (status:number, body:any) => {
var response = { statusCode: status, headers: { "Content-Type": "application/json" }, body: JSON.stringify(body) };
return response;
};
return sendRes(201, {pdf:your-base64-string} );
Then on the client (Nuxt in my case):
let res = await this.$store.dispatch('pdf/makePdf')
const linkSource = `data:application/pdf;base64,${res.data.pdf}`;
const downloadLink = document.createElement("a");
const fileName = "your-pdf-filename.pdf";
downloadLink.href = linkSource;
downloadLink.download = fileName;
downloadLink.click();
This open a download window and lets you save the file locally

Malformed request from aiohttp.ClientSession().post() with multiple image files

I'm still relatively new to Python and my first time to use aiohttp so I'm hoping someone can help spot where my problem is.
I have a function that does the following:
retrieves from the JSON payload two base64 strings - base64Front and base64Back
decode them, save to "images" folder
send the Front.jpg and Back.jpg to an external API
this external API expects a multipart/form-data
imgDataF = base64.b64decode(base64FrontStr)
frontFilename = 'images/Front.jpg'
with open(frontFilename, 'wb') as frontImgFile:
frontImgFile.write(imgDataF)
imgDataB = base64.b64decode(base64BackStr)
backFilename = 'images/Back.jpg'
with open(backFilename, 'wb') as backImgFile:
backImgFile.write(imgDataB)
headers = {
'Content-Type': 'multipart/form-data',
'AccountAccessKey': 'some-access-key',
'SecretToken': 'some-secret-token'
}
url = 'https://external-api/2.0/AuthenticateDoc'
files = [('file', open('./images/Front.jpg', 'rb')),
('file', open('./images/Back.jpg', 'rb'))]
async with aiohttp.ClientSession() as session:
async with session.post(url, data=files, headers=headers) as resp:
print(resp.status)
print(await resp .json())
The response I'm getting is status code 400 with:
{'ErrorCode': 1040, 'ErrorMessage': 'Malformed/Invalid Request detected'}
If I call the url via Postman and send the two jpg files, I get status code 200.
Hope someone can help here.
Thanks in advance.
Try using FormData to construct your request. Remove the content type from header and use it in FormData field as below:
data = FormData()
data.add_field('file',
open('Front.jpg', 'rb'),
filename='Front.jpg',
content_type='multipart/form-data')
await session.post(url, data=data)
Reference: https://docs.aiohttp.org/en/stable/client_quickstart.html#post-a-multipart-encoded-file

Ruby rest-client 401 Unauthorized after post of data

I'm new to using the rest-client. I know I'm missing something, but I am trying to do the following:
Post to a login endpoint to authenticate
After authentication, post csv text to another endpoint that requires a logged in user
The authentication portion is successful, however, I am getting a 401 Unauthorized when step 2 occurs.
rest_client = RestClient
login_response = #global_rest_client.post(
host + 'LOGIN ENDPOINT',
{ userName: 'user', password: 'password'},
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
)
import_response = rest_client.post(
host + 'IMPORT DATA ENDPOINT',
headers: { 'X-System-Name': 'AndroidMobile', 'Content-Type': 'multipart/form-data },
csv: csv_string
)
My understanding of how authentication works could be wrong. My assumption is that as long as the same instance of the client has a successful login, then the post of csv data would also be successful.
I appreciate any input.
HTTP (1.1) is stateless so a request does not contain any information about previous requests unless that information is encoded and added to the request in some way (e.g. cookies or headers). So when you make your import request the server does not know if/that you are authenticated even though you just made a login request.
You'll have to include the token you receive from your login request in subsequent requests. This should go in the 'Authorization' header.
For example:
auth_token = login_response["success"]["token"] # or whatever the key is for the token
import_response = rest_client.post(
host + 'IMPORT DATA ENDPOINT',
headers: { 'Authorization': "Bearer #{auth_token}", 'X-System-Name': 'AndroidMobile', 'Content-Type': 'multipart/form-data },
csv: csv_string
)
The way authentication works depends on the server and can be different in different cases. So the site you are accessing might expect the Authorization header to be like "Token #{auth_token}" or anything else, but they should mention it in their documentation.

CORs error when accessing Square V2 API

I'm making a client-side request out to V2 of the Square API using Vue and Axios. My Vue component is as follows:
import axios from 'axios';
export default {
mounted() {
var instance = axios.create({
baseURL: 'https://connect.squareup.com/v2/',
timeout: 1000,
headers: {
'Authorization': 'Bearer xxxxxxxxxxxxxxxxx',
'Accepts': 'application/json',
'Content-Type': 'application/json'
}
});
instance.get('catalog/list')
.then(function (response) {
console.log(response);
}) ;
}
}
However, when I make that call, I receive the following error:
Failed to load https://connect.squareup.com/v2/catalog/list: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://local-env.dev' is therefore not allowed access. The response had HTTP status code 403.
That error suggests that there is some configuration that has to happen on the Square side, but I saw no opportunity to whitelist domains, etc.
Has anyone come across this error before, regardless of service, and if so, how did you resolve?
I don't think the Square API supports being called from a browser. I used Postman to do an OPTIONS request on https://connect.squareup.com/v2/catalog/list and the response was a NOT_FOUND. The OPTIONS request is needed for proper CORS support.
Plus, if you did this, I would think your auth token would need to be sent to the client -- thus exposing it to everyone. It looks like the Square API is only designed to be called from a server. But that is just based on me skimming the docs a bit. I have no experience using their API.
When doing OAuth authorization request you are not supposed to do it from your application. Create and URL with the parameters and open it in a new browser window or tab, Something like:
const grants='MERCHANT_PROFILE_READ CUSTOMERS_READ CUSTOMERS_WRITE PAYMENTS_READ PAYMENTS_WRITE PAYMENTS_WRITE_ADDITIONAL_RECIPIENTS PAYMENTS_WRITE_IN_PERSON';
const params = new HttpParams()
.set('scope', grants)
.set('client_id', <YourSquareApplicationId>)
.set('state', '1878789');
const requestUrl = `${<squareUrl>}/oauth2/authorize?${params.toString()}`;
window.open(requestUrl, "_blank");
That new window is supposed to ask the end user to login to his account and accept or deny the request.

Ionic 2 ASP APi token request

I'm Trying to retrieve a bearer token from my ASP API from my ionic2 app.
I have enabled CORS on the API as shown below:
var cors = new EnableCorsAttribute("*", "*", "*");
config.EnableCors(cors);
This enabled me to form a POST request from my ionic 2 app to my API in order to register a user. This works wonderfully.
The request I used for this is as shown below:
let headers = new Headers({
'Content-Type': 'application/json'
});
let options = new RequestOptions({
headers: headers
});
let body = JSON.stringify({
Email: credentials.email,
Password: credentials.password,
ConfirmPassword: credentials.confirmPassword
});
return this.http.post('http://localhost:34417/api/Account/Register', body, options)
However when I try to retrieve a token from my API I receive the following error:
No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8100' is therefore not allowed access.
The request I'm using to try and retrieve the token is as follows:
let body = "grant_type=password" + "&userName=" + credentials.email + "&password=" + credentials.password;
let headers = new Headers({ 'Content-Type': 'application/x-www-form-urlencoded' });
let options = new RequestOptions({ headers: headers });
return this.http.post('http://localhost:34417/token', body, options)
This is the only request that is throwing this error, all other requests to my API work fine.
Have I missed anything, or am I doing something wrong?
var cors = new EnableCorsAttribute("*", "*", "*");
Looks like you are setting Access-Control-Allow-Origin as *.
Check MDN CORS Requests with credentials.
Credentialed requests and wildcards
When responding to a credentialed request, the server must specify an
origin in the value of the Access-Control-Allow-Origin header, instead
of specifying the "*" wildcard.
You will have to set a specific url if you use credentials.
Or if you only intend to use only for ionic 2, you could avoid the cors issue by setting a proxy.
According to the official blog:
The proxies settings contain two things: the path you use to access them on your local Ionic server, and the proxyUrl you’d ultimately like to reach from the API call.
{
"name": "ionic-2-app",
"app_id": "my_id",
"proxies": [
{
"path": "/api",
"proxyUrl": "http://localhost:34417/api"
}
]
}
Ionic serve command by default will start server on localhost:8100.
The set proxy will hit your http://localhost:34417/api.
Your path in the requests will be to the localhost:8100/api instead of your actual server.

Resources