Does Client Lib/SDK reach out for OCR? - azure-form-recognizer

Sorry for the dumb question, for the following sample code below, does it reach out to the real Azure Cloud for OCR process or just perform it locally?
const { FormRecognizerClient, AzureKeyCredential } = require("#azure/ai-form-recognizer"); // v3.2
const fs = require("fs");
const readStream = fs.createReadStream(MyLocalFile);
const client = new FormRecognizerClient(endpoint, new AzureKeyCredential(apiKey));
const poller = await client.beginRecognizeInvoices(readStream, {
onProgress: (state) => {
console.log(`status: ${state.status}`);
}
});
const [invoice] = await poller.pollUntilDone();

This is the Form Recognizer SDK and it will call the Analyze Invoice API on the cloud hosted service to analyze the document.

Related

`S3Client.send()` doesn't return `VersionId`

I have a bucket which has versioning enabled. In my ReactJS app, I need to upload files to the bucket and receive the new object metadata. I use S3 Client with PutObjectCommand to do the upload. The documentation here states:
Versioning
If you enable versioning for a bucket, Amazon S3 automatically generates a unique version ID for the object being stored. Amazon S3 returns this ID in the response. When you enable versioning for a bucket, if Amazon S3 receives multiple write requests for the same object simultaneously, it stores all of the objects.
So, I expect to receive a VersionId. But not only this field is undefined, but also other fields like requestId or `cfId.
Here is my module code:
import {
PutObjectCommand,
S3Client
} from '#aws-sdk/client-s3';
const S3_BUCKET_NAME = process.env.S3_BUCKET_NAME;
const AWS_REGION = process.env.AWS_REGION;
const AWS_ACCESS_KEY = process.env.AWS_ACCESS_KEY;
const AWS_SECRET_KEY = process.env.AWS_SECRET_KEY;
const client = new S3Client({
region: AWS_REGION,
credentials: {
accessKeyId: AWS_ACCESS_KEY,
secretAccessKey: AWS_SECRET_KEY
}
});
const uploadToS3 = async function (fileToUpload) {
const data = await fileToUpload.arrayBuffer();
const params = {
Bucket: S3_BUCKET_NAME,
Key: fileToUpload.name,
Body: data
};
const command = new PutObjectCommand(params);
const result = await client.send(command);
console.log(result); // requestId: undefined, extendedRequestId: undefined, cfId: undefined
console.log(`VersionId: ${result.VersionId}`); // VersionId: undefined
}
export default {
uploadToS3
}
Have I missed anything here?

Problem with listening to messages OnSnapshot with a React Native Firebase Messaging App

I'm trying to create a React Native messaging app with the firebase SDK. In the chat screen I am trying to listen to updated messages in my firestore database. I'm following a lot of the code shown in this github repository https://github.com/ReactNativeSchool/react-native-firebase-chat-app, but it uses react-native-firebase and I am using the SDK which is causing making it hard for me to find the equivalent code with the firebase SDK. What am I doing wrong in the below code that is giving me the following error when I open the screen:
undefined is not a function (near '...(0,_firebaseConfig.listenToMessages)(threadID).onSnapshot...')
I believe it has to do with me not converting from react-native-firebase to the firebase SDK correctly, but I'm not sure.
Below is my listenToThreads code from the firebaseConfig file where I do all my firebase functions. Below that is the part I commented out that returned the values within that collection.
export const listenToMessages = async (threadID) => {
return firebase.firestore()
.collection('threads')
.doc(threadID)
.collection('messages');
// try {
// const q = query(collection(db, "threads"), where("tid", "==", threadID));
// const doc = await getDocs(q);
// const data = doc.docs[0].data();
// return data.messages;
// } catch {
// return [];
// }
};
and here is my onSnapshot code which I'm running inside a working UseFocusEffect hook.
const unsubscribe = listenToMessages(threadID).onSnapshot(
querySnapshot => {
const formattedMessages = querySnapshot.docs.map(doc => {
return {
_id: doc.id,
text: '',
createdAt: new Date().getTime(),
user: {}
};
});
setMessages(formattedMessages);
},
);
return () => {
unsubscribe();
};
The listenToMessages function should not be async.
It returns a promise rather than the doc you want. ✌️

Send FormData object and File in a single Axios POST request

I currently have a Spring boot API controller method (below) that accepts an object as well as a MultiPart file. I am able to successfully send a POST request via Postman however I am now struggling to make this post request via my front-end ReactJS application using Axios.
#PostMapping(
path = "/upload",
consumes = {
MediaType.APPLICATION_JSON_VALUE,
MediaType.MULTIPART_FORM_DATA_VALUE
},
headers = {
"Content-Type=multipart/form-data"
}
)
public SoundProfile uploadSoundProfile(Authentication auth,
#RequestPart("soundProfileRequest") SoundProfileRequest soundProfileRequest,
#RequestPart("audio_file") MultipartFile audio_file){
return soundProfileService.uploadSoundProfile(auth, soundProfileRequest, audio_file);
}
Postman POST request:
The following is my service method to process the object and file which is responsible for saving the object to a MySQL database and then storing the file in an Amazon S3 bucket.
public SoundProfile uploadSoundProfile(Authentication auth, SoundProfileRequest soundProfileRequest, MultipartFile audio_file) {
if (audio_file.isEmpty()){
throw new IllegalStateException("no audio file received");
}
AppUser current_user = appUserRepository.findByEmail(auth.getName())
.orElseThrow(
() -> new IllegalStateException("User not found")
);
Map<String, String> metadata = new HashMap<>();
metadata.put("Content-Type", audio_file.getContentType());
metadata.put("Content-Length", String.valueOf(audio_file.getSize()));
String soundPath = UUID.randomUUID().toString();
SoundProfile soundProfile = new SoundProfile(
soundPath, // SoundPath = S3 key
soundProfileRequest.getCaseBrand(),
soundProfileRequest.getCaseModel(),
soundProfileRequest.getSwitches(),
soundProfileRequest.getKeycaps(),
soundProfileRequest.getStabilizers(),
soundProfileRequest.getLube(),
soundProfileRequest.getMods(),
current_user
);
// save sound profile to database
soundProfileRepository.save(soundProfile);
String path = String.format("%s/%s", BucketName.KEYBOARD_AUDIO_BUCKET.getBucketName(), current_user.getUserId());
String filename = String.format("%s-%s", audio_file.getOriginalFilename(), soundPath);
// Save audio file to s3 bucket
try {
fileStore.saveAudio(
path,
filename,
Optional.of(metadata),
audio_file.getInputStream()
);
} catch (IOException e) {
throw new IllegalStateException(e);
}
return soundProfile;
}
I would like to send the SoundProfileRequest object and the multipart file separately, meaning I don't want to append the file to a FormData object, but I would still like to send the file along with the form fields in a single post request.
For example in my front-end React Component:
export default function UploadSoundProfile() {
const [caseBrand, setCaseBrand] = useState("");
const [caseModel, setCaseModel] = useState("");
const [switches, setSwitches] = useState("");
const [keycaps, setKeycaps] = useState("");
const [lube, setLube] = useState("");
const [stabilizers, setStabilizers] = useState("");
const [mods, setMods] = useState("");
const [selectedFile, setSelectedFile] = useState("");
const history = useHistory();
const createSoundProfile = (e) => {
e.preventDefault();
const url = "/sound-profile/upload";
const formData = new FormData();
formData.append('caseBrand', caseBrand);
formData.append('caseModel', caseModel);
formData.append('switches', switches);
formData.append('keycaps', keycaps);
formData.append('lube', lube);
formData.append('stabilizers', stabilizers);
formData.append('mods', mods);
**// SHOULD FILE ALSO BE APPENDED TO FORMDATA OBJECT HERE?**
formData.append('audio_file', selectedFile);
const config = {
headers: {
"content-type": "multipart/form-data"
}
}
uploadProfileService.createSoundProfile(url, formData, config);
history.push("/sound-profile/profile");
};
return (
...
)
}
Is there a way to make the POST request with Axios without appending the file to the FormData object while still making a single post request?
I am unsure of how to accomplish this, or if it is possible. I have seen other posts where a file is being .append() to a FormData object, but I am unsure if this will cause an error on the backend.
Thanks for any help in advance!

Error 400 Bad Request while Uploading Image to firebase storage in React Native

I am working on react native project connected to firebase. I am =using firebase storage ad=nd trying to upload a file to firebase storage But I get following error.
{code: 400, message: "Bad Request. Could not access bucket quickbuy-a0764.appspot.com","status":"Access_Bucket"}
I tried configuring my permissions but did not work for me.
example of Image Uri I am providing to put() is as follows
data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wCEAAk and so on
Now what should I do to resolve this issue?
let filename = values.images + Date.now();
let uri = values.images[0];
const uploadTask = storage.ref(`images/${filename}`).put(uri);
uploadTask.on("state_changed", (snapshot) => {
console.log(snapshot);
});
firebase.storage.Reference#put() accepts a Blob, Uint8Array or an ArrayBuffer. Because you are trying to upload a Data URI, which is a string, you need to use [firebase.storage.Reference#putString()`](https://firebase.google.com/docs/reference/js/firebase.storage.Reference#putstring).
To do this for a data URI, you would use:
someStorageRef.putString(uri, firebase.storage.StringFormat.DATA_URL);
Next, based on these lines:
const filename = values.images + Date.now();
let uri = values.images[0];
values.images is an array, which means that filename will end up being something similar to "[object Object],[object Object]1620528961143".
As I covered in this answer on your question yesterday, this is a poor way to generate IDs as it can lead to duplicates & collisions - use a Push ID instead.
const uri = /* ... */;
const rootRef = firebase.database().ref();
const filename = rootRef.push().key;
const uploadTask = storage.ref(`images/${filename}`)
.putString(uri, firebase.storage.StringFormat.DATA_URL);
uploadTask.on("state_changed", (snapshot) => {
console.log(snapshot);
});
Future Use with Version 9 of the SDK
import { getStorage, ref, uploadBytes } from "firebase/storage";
const uploadImage = async (values) => {
const filename = values.images + Date.now();
const uri = values.images[0];
// Create a root reference
const storage = getStorage();
// Create a reference to 'images/$filename.jpg'
const filesImagesRef = ref(storage, 1images/${filename}.jpg);
await uploadBytes(filesImagesRef, uri).then((snapshot) => {
console.log('Uploaded a blob or file!');
});
}
Let us know how this works for you!

GAE: Is there a way to authorize version endpoints with GCP OAuth redirect URLs?

I thought I was smart by using a custom version tag for my applications so I could predetermine the fully qualified version-URL. And my integration tests work wonders when I do this, however, I can't figure out a way around my OAuth rules.
Currently, wildcard Authorized redirect URIs aren't allowed:
What I want to achieve is basically a fully functional app (consist of three services) that has yet to be promoted. That way our testers can greenlight to deployment before the deployment.
Anyone got any idea is such a thing is possible?
So thanks to #sllopis's comment I ended up creating a login service that took care of the redirecting to multiple versions of the same service.
It isn't the perfect solution, but it is one we can use. OAuth to our unpublished apps.
//#ts-check
const fastify = require("fastify")({ logger: true });
const {
google: {
auth: { OAuth2 }
}
} = require("googleapis");
const { googleLoginCallback, googleClientId, googleClientSecret } = process.env;
const defaultScope = [
"https://www.googleapis.com/auth/plus.me",
"https://www.googleapis.com/auth/userinfo.email"
];
const getGoogleRedirecturl = () =>
new OAuth2(
googleClientId,
googleClientSecret,
googleLoginCallback
).generateAuthUrl({
access_type: "offline",
prompt: "consent",
scope: defaultScope
});
fastify.get("/login", (req, reply) => {
const { versionEndpoint } = req.query;
const encodedEndpoint = encodeURIComponent(versionEndpoint);
const query = `&state=${encodedEndpoint}`;
reply.redirect(getGoogleRedirecturl() + query);
});
fastify.get("/login/callback", (req, reply) => {
const { code, state } = req.query;
const endpoint = decodeURIComponent(state);
reply.redirect(endpoint + "?code=" + code);
});
fastify
.listen(3000)
.then(str => {
fastify.log.info(`server listening on ${fastify.server.address()}`, str);
})
.catch(err => {
fastify.log.error(err);
process.exit(1);
});

Resources