POST requests to Flask from Unity result in `null` values - unity3d

After getting this demo server working I am able return GET requests from it to Unity, but when I would try to send data from Unity to the local server using POST requests it would only show null values added into the server. This is the code I was using in Unity:
IEnumerator Upload()
{
WWWForm form = new WWWForm();
form.AddField("charge","+4/3");
form.AddField("name", "doubletop");
using (UnityWebRequest www = UnityWebRequest.Post("http://localhost:5000/quarks/", form))
{
yield return www.SendWebRequest();
if (www.isNetworkError || www.isHttpError)
{
Debug.Log(www.error);
}
else
{
Debug.Log("Form upload complete!");
}
}
}
I would get "Form upload complete!" in the console, and GET requests would work, but those null values kept coming.

I modified my Upload() method to the PostRequest() in this example, and now it works!
Here's the full code:
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
public class HTTP : MonoBehaviour
{
void Start()
{
// A correct website page.
StartCoroutine(GetRequest("localhost:5000/quarks"));
PostData();
StartCoroutine(GetRequest("localhost:5000/quarks"));
// A non-existing page.
//StartCoroutine(GetRequest("https://error.html"));
}
IEnumerator GetRequest(string uri)
{
using (UnityWebRequest webRequest = UnityWebRequest.Get(uri))
{
// Request and wait for the desired page.
yield return webRequest.SendWebRequest();
string[] pages = uri.Split('/');
int page = pages.Length - 1;
if (webRequest.isNetworkError)
{
Debug.Log(pages[page] + ": Error: " + webRequest.error);
}
else
{
Debug.Log(pages[page] + ":\nReceived: " + webRequest.downloadHandler.text);
}
}
}
[Serializable]
public class Quark
{
public string name;
public string charge;
}
public void PostData()
{
Quark gamer = new Quark();
gamer.name = "doublebottom";
gamer.charge = "4/3";
string json = JsonUtility.ToJson(gamer);
StartCoroutine(PostRequest("http://localhost:5000/quarks", json));
}
IEnumerator PostRequest(string url, string json)
{
var uwr = new UnityWebRequest(url, "POST");
byte[] jsonToSend = new System.Text.UTF8Encoding().GetBytes(json);
uwr.uploadHandler = (UploadHandler)new UploadHandlerRaw(jsonToSend);
uwr.downloadHandler = (DownloadHandler)new DownloadHandlerBuffer();
uwr.SetRequestHeader("Content-Type", "application/json");
//Send the request then wait here until it returns
yield return uwr.SendWebRequest();
if (uwr.isNetworkError)
{
Debug.Log("Error While Sending: " + uwr.error);
}
else
{
Debug.Log("Received: " + uwr.downloadHandler.text);
}
}
}

Related

Unity HTTP/1.1 400 Bad Request while fetching data from Mongo Atlas

I'm trying to fetch a collection with Mongo Atlas Data API. In API logs, Status seems as "OK" but i'm getting "Bad Request" error in Unity editor. Am I missing something? Thanks for helps.
using UnityEngine;
using UnityEngine.Networking;
using System.Collections;
using System;
using System.Text;
public class Queries : MonoBehaviour
{
public static void DumpToConsole(object obj)
{
var output = JsonUtility.ToJson(obj);
Debug.Log(output);
}
void OnMouseDown()
{
StartCoroutine(GetDB());
IEnumerator GetDB() {
WWWForm form = new WWWForm();
form.AddField("dataSource","Cluster0");
form.AddField("database","Herbarium");
form.AddField("collection","Herbs-Specs");
/*byte [] bodyRaw = form.data;
string formInput = Convert.ToBase64String(bodyRaw);*/
UnityWebRequest www = UnityWebRequest.Post("https://data.mongodb-api.com/**********/data/v1/action/find", form);
www.SetRequestHeader("Content-Type", "application/json");
www.SetRequestHeader("Access-Control-Request-Headers", "*");
www.SetRequestHeader("api-key", "***********");
yield return www.SendWebRequest();
if (www.result != UnityWebRequest.Result.Success)
{
Debug.Log(www.error);
}
else
{
DumpToConsole(www.downloadHandler.text);
}
}
}
}

How would I get a Texture in the project and send it over to discord using a webhook? Unity

What I am trying to do is take a texture(any texture) from unity and use a webhook from discord to send it to discord.
This is what I have so far keep in mind I started coding not long ago so I'm not very familiar with this;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
public class SendMessage : MonoBehaviour
{
public string Message, Subject;
public string webhook;
public Texture2D screenshot;
// Start is called before the first frame update
void Start()
{
}
IEnumerator SendWebHook(string link, string message, System.Action<bool> action)
{
WWWForm form = new WWWForm();
form.AddField("content", message + screenshot.EncodeToPNG());
using (UnityWebRequest www = UnityWebRequest.Post(link, form))
{
yield return www.SendWebRequest();
if(www.isNetworkError || www.isHttpError)
{
Debug.Log(www.error);
action(false);
}
else
{
action(true);
}
}
}
public void send()
{
StartCoroutine(SendWebHook(webhook, Subject + Message, (success) =>
{
if(success)
{
Debug.Log("good");
}
}));
}
}

Why does Post request to OpenAI in Unity result in error 400?

I am trying to use GPT3 in a game I am making but I can't seem to be able to call the OpenAI API correctly. I got most of this from the Unity docs.
Here is the code I am using:
public class gpt3_complete : MonoBehaviour
{
public string model;
public string prompt;
public int len;
public string temp;
public string api_key = "<key>";
void Start()
{
StartCoroutine(Upload());
}
IEnumerator Upload()
{
WWWForm form = new WWWForm();
form.AddField("model", model);
form.AddField("prompt", prompt);
form.AddField("max_tokens", len);
form.AddField("temperature", temp);
//form.headers.Add("Authorization", "Bearer "+api_key);
using (UnityWebRequest www = UnityWebRequest.Post("https://api.openai.com/v1/completions", form))
{
www.SetRequestHeader("Authorization", "Bearer " + api_key);
www.SetRequestHeader("Content-Type", "application/json");
yield return www.SendWebRequest();
if (www.result != UnityWebRequest.Result.Success)
{
Debug.Log(www.error);
}
else
{
Debug.Log(www.result);
Debug.Log("Form upload complete!");
}
}
}
}
This always returns: 400 Bad Request.
The GPT3 docs can be found here: https://beta.openai.com/docs/api-reference/completions/create
Any idea why this is?
This is my first time making any web requests in unity so I'm probably missing something obvious.
Thanks!
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
using System.Text;
public class OpenAIRequest : MonoBehaviour
{
public string apiKey = "YOUR_API_KEY_HERE";
public string prompt = "Once upon a time, in a land far far away, there lived a brave knight";
public string model = "text-davinci-002";
public int maxTokens = 100;
void Start()
{
StartCoroutine(GetOpenAIResponse());
}
IEnumerator GetOpenAIResponse()
{
string url = "https://api.openai.com/v1/engines/" + model + "/completions";
string requestData = "{\"prompt\": \"" + prompt + "\", \"max_tokens\": " + maxTokens + "}";
UnityWebRequest request = new UnityWebRequest(url, "POST");
byte[] bodyRaw = Encoding.UTF8.GetBytes(requestData);
request.uploadHandler = (UploadHandler)new UploadHandlerRaw(bodyRaw);
request.downloadHandler = (DownloadHandler)new DownloadHandlerBuffer();
request.SetRequestHeader("Content-Type", "application/json");
request.SetRequestHeader("Authorization", "Bearer " + apiKey);
yield return request.SendWebRequest();
if (request.result != UnityWebRequest.Result.Success)
{
Debug.Log(request.error);
}
else
{
string response = request.downloadHandler.text;
Debug.Log(response);
}
}
}
result

Getting Data from HTTP Request Xamarin

I want to get and pass data from my HTTPWebRequest to my sync page. I am new to MVVM so I don't know if I am correct but so far I can check if there is a result. I tried to watch a lots of video tutorials and forums still I can't find what I need. I was hoping you guys have a answer for me. I have been struggling with this for a week now.
The flow of my project:
- The user will login when it is correct, The user will be redirected to my sync page where it will get all the users data from my server and insert the data into SQLite Database.
My questions are:
1. How can I get the data and specific data from my HTTPWebRequest?
2. Is my HTTPWebRequest service correct?
3. Is my MVVM correct?
4. Is my navigation to my next page is correct?
My code:
LoginPage.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TBSMobileApplication.Data;
using TBSMobileApplication.ViewModel;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace TBSMobileApplication.View
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class LoginPage : ContentPage
{
public LoginPageViewModel loginModel;
public LoginPage ()
{
InitializeComponent ();
BindingContext = new LoginPageViewModel();
MessagingCenter.Subscribe<LoginPageViewModel,string>(this, "Login Alert", (sender,Username) =>
{
DisplayAlert("Login Error", "Please fill-up the form", "Ok");
});
MessagingCenter.Subscribe<LoginPageViewModel, string>(this, "Connected", (sender, Username) =>
{
DisplayAlert("Connection Info", "Connected", "Ok");
});
MessagingCenter.Subscribe<LoginPageViewModel, string>(this, "Not Connected", (sender, Username) =>
{
DisplayAlert("Connection Info", "Not Connected", "Ok");
});
MessagingCenter.Subscribe<LoginPageViewModel, string>(this, "Http", (sender, Username) =>
{
DisplayAlert("Login Error", "Username or Password is incorrect", "Ok");
});
entUsername.Completed += (object sender, EventArgs e) =>
{
entPassword.Focus();
};
}
protected async Task OnAppearingAsync()
{
var db = DependencyService.Get<ISQLiteDB>();
var conn = db.GetConnection();
if (conn != null)
{
await conn.CreateTableAsync<UserTable>();
await conn.CreateTableAsync<RetailerTable>();
await conn.CreateTableAsync<ContactsTable>();
}
base.OnAppearing();
}
}
}
LoginPageViewModel.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Net;
using System.Text;
using System.Windows.Input;
using TBSMobileApplication.View;
using Xamarin.Essentials;
using Xamarin.Forms;
namespace TBSMobileApplication.ViewModel
{
public class LoginPageViewModel : INotifyPropertyChanged
{
void OnProperyChanged(string PropertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(PropertyName));
}
public string username;
public string password;
public string Username
{
get { return username; }
set
{
username = value;
OnProperyChanged(nameof(Username));
}
}
public string Password
{
get { return password; }
set
{
password = value;
OnProperyChanged(nameof(Password));
}
}
public ICommand LoginCommand { get; set; }
public LoginPageViewModel()
{
LoginCommand = new Command(OnLogin);
}
public void OnLogin()
{
if (string.IsNullOrEmpty(Username) || string.IsNullOrEmpty(Password))
{
MessagingCenter.Send(this, "Login Alert", Username);
}
else
{
var current = Connectivity.NetworkAccess;
if (current == NetworkAccess.Internet)
{
var link = "http://192.168.1.25:7777/TBS/test.php?User=" + Username + "&Password=" + Password;
var request = HttpWebRequest.Create(string.Format(#link));
request.ContentType = "application/json";
request.Method = "GET";
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
if (response.StatusCode != HttpStatusCode.OK)
{
Console.Out.WriteLine("Error fetching data. Server returned status code: {0}", response.StatusCode);
}
else
{
using (StreamReader reader = new StreamReader(response.GetResponseStream()))
{
var content = reader.ReadToEnd();
if (content.Equals("[]") || string.IsNullOrWhiteSpace(content) || string.IsNullOrEmpty(content))
{
MessagingCenter.Send(this, "Http", Username);
}
else
{
App.Current.MainPage.Navigation.PushAsync(new DatabaseSyncPage(), true);
}
}
}
}
}
else
{
MessagingCenter.Send(this, "Not Connected", Username);
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
}

Unity3D WWW Post data async

I want to post a JSON to a website using the WWW class, But I get this answer from the server: "Synchronization problem.". Is there a way to change from sync to async? Thank You
You can run your WWW job in a coroutine (WWW supports this well):
using UnityEngine;
public class PostJSON : MonoBehaviour {
void Start () {
string url = "http://your_url_endpoint";
WWWForm form = new WWWForm();
Hashtable headers = form.headers;
headers["Content-Type"] = "application/json";
Hashtable data = new Hashtable();
data["message"] = "a sample message sent to service as json";
string json = JSON.JsonEncode(data);
byte[] bytes = Encoding.UTF8.GetBytes(json);
WWW www = new WWW(url, bytes, headers);
StartCoroutine(WaitForRequest(www));
}
IEnumerator WaitForRequest(WWW www)
{
yield return www
// check for errors
if (www.error == null)
{
Debug.Log("WWW Ok!: " + www.data);
} else {
Debug.Log("WWW Error: "+ www.error);
}
}
}
Here you have a running project which I use to talk to a json based REST service called KiiCloud:
http://blog.kii.com/?p=2939
HTH
The answer from German was very helpful, but I made some tweaks so that it'll compile and run (with sample serialization / deserialization bits).
Just pass in the BaseUrl you want to post to, i.e.
http://www.domain.com/somecontroller/someaction or whatever.
using System;
using System.Text;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[Serializable]
public class Person
{
public string Name;
}
[Serializable]
public class Response
{
public string SomeValue;
}
public class PostJSON : MonoBehaviour
{
public string BaseUrl;
private WWWForm form;
private Dictionary<string, string> headers = null;
void Start ()
{
var basUrlNotSpecified = string.IsNullOrEmpty(BaseUrl);
if(basUrlNotSpecified)
{
Debug.LogWarning("BaseUrl value not specified. Post abandoned.");
return;
}
form = new WWWForm();
headers = form.headers;
headers["Content-Type"] = "application/json";
headers["Accept"] = "application/json";
var person = new Person
{
Name = "Iulian Palade"
};
var json = JsonUtility.ToJson(person);
byte[] bytes = Encoding.UTF8.GetBytes(json);
WWW www = new WWW(BaseUrl, bytes, headers);
StartCoroutine(WaitForRequest(www));
}
IEnumerator WaitForRequest(WWW www)
{
yield return www;
if (www.error == null)
{
Debug.Log("WWW Ok!: " + www.text);
var response = JsonUtility.FromJson<Response>(www.text);
Debug.Log(response.SomeValue);
}
else
{
Debug.Log("WWW Error: "+ www.error);
}
}
}