How to access Cloud Storage file from App running at local - server-error

I have just success on writing the file to the Google cloud Storage and reading it. Everything is fine after I deploy the app to appspot, but I got errors when running it local:
INTERNAL_SERVER_ERROR
Caused by:java.io.IOException
at com.google.appengine.api.files.FileServiceImpl.translateException(FileServiceImpl.java:586)
at com.google.appengine.api.files.FileServiceImpl.makeSyncCall(FileServiceImpl.java:561)
......
Does any one of you know how to access Google Cloud Storage file from localhost?

The App Engine developer test environment supports a local simulation of Google Cloud Storage but doesn't provide RPC access to the real thing. So, your code should work in both environments, but you should think of the two modes as having distinct name spaces and content. So if, for example, your code expects to see a particular bucket foo containing an object bar, you'll want to separately create that bucket/object and ensure it contains reasonable content in order for the local developer mode to work as expected.

I was able to find and use the simulated service mentioned above. Unfortunately for this thread, I don't know Java. But it's usage in Python is as follows...
$ python2.7 google_appengine/google/appengine/tools/api_server.py --application myapp
(Note that api_server.py requires Python 2.7 because it depends on the argparse module.)
Somebody else will have to figure out how to do the same in Java. Sorry. :(
EDIT:
The api_server.py is in the base directory:
$ python2.7 google_appengine/api_server.py

To run it "pseudo" locally (like on a command-line), you should first deploy it and then use HttpClient to connect to your server. That way you can interact with your servlet/jsp from the command line and not have to submit forms with file attachments
Sample code [You can certainly get more creative than that]
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.client.ClientProtocolException;
public class FileUploaderClient {
/**
* #param args
*/
public static void main(String[] args) throws ClientProtocolException, IOException{
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://<app-version>.<app-name>.appspot.com/<servlet-name>");
MultipartEntity reqEntity = new MultipartEntity();
FileBody bin = new FileBody(new File("<File you want to upload>"));
reqEntity.addPart("file", bin);
httppost.setEntity(reqEntity);
HttpResponse response = httpclient.execute(httppost);
System.out.println(response.getStatusLine());
}
}
Now you would have the ability to call your servlet in a loop for example instead of submitting your form multiple times

Related

FastApi Test Client executing the internal api call

This is the first time I'm trying to write test cases.
I've got a simple FastAPI application and I'm trying to create tests with unittest module.
My goal is to test how app behaves for success case
I've got a simple route in my app:
from fastapi import APIRouter,Request
import requests
router = APIRouter()
#router.post("/demo_router")
async def demo_api(request: Request):
# now calling some private APi's
resp = requests.post("https://example.com", json=data)
return {"resp_data": resp.json()}
Now in my unittest module I'm trying to patch above api. I'm using unittest.mock but I'm getting very strange behavior.
import unittest
from fastapi.testclient import TestClient
from unittest.mock import patch
from main import app
class DemoViewTestCase(unittest.TestCase):
def test_demo_api(self):
with patch('src.endpoints.demo_module.demo_api') as mocked_post:
mocked_post.return_value.status_code = 200
mocked_post.return_value.json = {
"message": "request accepted",
"success": True
}
url = router.url_path_for('demo_api') #fetch the api router
client = TestClient(app)
response = client.post(url, json={"id": "BXBksk8920", "name": "Pjp"})
My problem is TestClient is calling the api and executing it. So it is triggering the internal call "https://example.com" which is causing some execution in the pipelines. So how can I overcome this?
Internal Api shouldn't trigger, I should even mock that? Any solution for that?
When testing all the code will be executed. Thus also the calls to the APIs. If you don't want this, you have to provide mock APIs (postman, mockon and many others provide this).
Because you don't want to be bothered to change the URL's etc when you are testing etc, you could look at automating this.
One way of doing this is to provide all URLs for external APIs using pedantic BaseSettings
config.py:
from pydantic import BaseSettings
class Settings(BaseSettings):
external_api_url: str = "https://api.example.com"
And use this in your code:
settings = Settings() # scans environment for any matching env settings!
...
resp = requests.post(setting.external_api_url, json=data)
In your tests you can override these settings:
settings = Settings(external_api_url="https://mockservice")
This is documented further in Pydantic BaseSettings
There are more way do enhance testing and this is found at the FastAPI documentation:
Dependency Override: https://fastapi.tiangolo.com/advanced/testing-dependencies/
Use different databases for testing: https://fastapi.tiangolo.com/advanced/testing-database/

How to run server-only code once on server startup in Next.js?

I am trying to access my User objection.js model from getStaticProps and getStaticPaths.
However, I need to run
import Knex from "knex";
import knexfile from "./knexfile";
import { Model } from "objection";
function setupDB() {
const db = Knex(knexfile[process.env.NODE_ENV]);
Model.knex(db);
}
on server startup.
When I do
const users = await User.query();
inside getStaticPaths, I get Error: no database connection available for a query. You need to bind the model class or the query to a knex instance. error.
I tried running setupDB() inside _app.js with typeof window === "undefined" check, but just importing Knex and objection in _app.js throws an error.
Where should I run this? I really really want to avoid extending server.js.
(I should add there was a discussion on next.js github, but not sure if there's a way to do it specific to Objection.js, or any recent development.

Flask Mail doesn't work when deployed on Ubuntu

I'm sending password reset email with Flask-Mail. When I tried it on development server everything works fine. When deployed on Ubuntu (using NGINX, Gunicorn) sending the email leads after a long loading time to Error 502 so I don't think there's problem in sending the email rather there's a problem in the settings.
My init code after deploying:
import os
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_bcrypt import Bcrypt
from flask_login import LoginManager
from flask_mail import Mail
from flask_socketio import SocketIO
import json
with open('/etc/config.json') as config_file:
config = json.load(config_file)
app = Flask(__name__)
app.config['SECRET_KEY'] = config.get('SECRET_KEY')
app.config['SQLALCHEMY_DATABASE_URI'] = config.get('SQLALCHEMY_DATABASE_URI')
db = SQLAlchemy(app)
bcrypt = Bcrypt(app)
login_manager = LoginManager(app)
login_manager.login_view = 'login'
login_manager.login_message_category = 'info'
app.config['MAIL_SERVER'] = 'smtp.gmail.com'
app.config['MAIL_PORT'] = 587
app.config['MAIL_USE_TLS'] = True
app.config['MAIL_USERNAME'] = config.get('EMAIL_USER')
app.config['MAIL_PASSWORD'] = config.get('EMAIL_PASS')
mail = Mail(app)
In config.json the information is correctly provided
Disabling CAPTCHA for clients
If you are not using 2-factor authentication and you have verified the credentials in your Python source are correct, follow these steps:
1.) Login to gmail in your browser
2.) Navigate to the DisplayUnclockCaptcha page.
3.) Click the continue button, and you will see the message 'Account access enabled Please try signing in to your Google account again from your new device or application.'
4.)Run your Python script - your login attempt should be successful.
Hello i might be a little late for this, but thomas your problem is caused because of linode which is probably the deployment server that you used, decided to default block the ports that you are using as you can see it here.
https://www.linode.com/community/questions/19082/i-just-created-my-first-linode-and-i-cant-send-emails-why
if u follow the process given it certainly will work

Qt WebView - intercept loading of JS/CSS Libraries to load local ones

I've been looking for a while through documentation to find a way to accomplish this and haven't been successful yet. The basic idea is, that I have a piece of html that I load through Qt's webview. The same content can be exported to a single html file.
This file uses Libraries such as Bootstrap and jQuery. Currently I load them through CDN which works when online just fine. However, my application also needs to run offline. So I'm looking for a way to intercept loading of the Libraries in Qt and serve a locally saved file instead. I've tried installing a https QWebEngineUrlSchemeHandler, but that never seems to trigger the requestStarted method on it.
(PyQT example follows)
QWebEngineProfile.defaultProfile().installUrlSchemeHandler(b'https', self)
If I use a different text for the scheme and embed that into the page it works, so my assumption is that it doesn't work as Qt has a default handler for it already registered. But that different scheme would fail in the file export.
Anyway, back to the core question; Is there a way to intercept loading of libraries, or to change the url scheme specifically within Qt only?
Got Further with QWebEngineUrlRequestInterceptor, now redirecting https requests to my own uri, which has a uri handler. However, the request never gets through to it, because: Redirect location 'conapp://webresource/bootstrap.min.css' has a disallowed scheme for cross-origin requests.
How do I whitelist my own conapp uri scheme?
Edit: For completeness sake, it turns out back when I originally stated the question, it was impossible to accomplish with PySide 5.11 due to bugs in it. The bug I reported back then is nowadays flagged as fixed (5.12.1 I believe) so it should now be possible to accomplish this again using Qt methods, however for my own project I'll stick to jinja for now which has become a solution for many other problems.
The following example shows how I've done it. It uses the QWebEngineUrlRequestInterceptor to redirect content to a local server.
As an example, I intercept the stacks.css for stackoverflow and make an obvious change.
import requests
import sys
import threading
from PyQt5 import QtWidgets, QtCore
from PyQt5.QtWebEngineWidgets import QWebEngineView, QWebEnginePage, QWebEngineProfile
from PyQt5.QtWebEngineCore import QWebEngineUrlRequestInterceptor, QWebEngineUrlRequestInfo
from http.server import HTTPServer, SimpleHTTPRequestHandler
from socketserver import ThreadingMixIn
# Set these to the address you want your local patch server to run
HOST = '127.0.0.1'
PORT = 1235
class WebEngineUrlRequestInterceptor(QWebEngineUrlRequestInterceptor):
def patch_css(self, url):
print('patching', url)
r = requests.get(url)
new_css = r.text + '#mainbar {background-color: cyan;}' # Example of some css change
with open('local_stacks.css', 'w') as outfile:
outfile.write(new_css)
def interceptRequest(self, info: QWebEngineUrlRequestInfo):
url = info.requestUrl().url()
if url == "https://cdn.sstatic.net/Shared/stacks.css?v=596945d5421b":
self.patch_css(url)
print('Using local file for', url)
info.redirect(QtCore.QUrl('http:{}:{}/local_stacks.css'.format(HOST, PORT)))
class ThreadingHTTPServer(ThreadingMixIn, HTTPServer):
"""Threaded HTTPServer"""
app = QtWidgets.QApplication(sys.argv)
# Start up thread to server patched content
server = ThreadingHTTPServer((HOST, PORT), SimpleHTTPRequestHandler)
server_thread = threading.Thread(target=server.serve_forever)
server_thread.daemon = True
server_thread.start()
# Install an interceptor to redirect to patched content
interceptor = WebEngineUrlRequestInterceptor()
profile = QWebEngineProfile.defaultProfile()
profile.setRequestInterceptor(interceptor)
w = QWebEngineView()
w.load(QtCore.QUrl('https://stackoverflow.com'))
w.show()
app.exec_()
So, the solution I went with in the end was, first, introduce jinja templates. Then, using those the template would have variables and blocks set based on export or internal use and from there I did not need the interceptor anymore.

Is there a way to add detailed remote crash reporting to a Flex Air application?

I will be releasing my Air/Flex application soon, but I am pretty sure there are a couple of bugs that may pop up on the various platforms that Air is available for. So I was wondering if there is a way to implement a mechanism, that would send an error report, logging where the error happened, to a remote server each time an app crashes? This way I might catch errors that otherwise would go unnoticed.
Global error handling is now supported in Flash 10 and AIR2. More info on that here: http://help.adobe.com/en_US/air/reference/html/flash/events/UncaughtErrorEvent.html
Using that kind of functionality to catch uncaught exceptions; you can submit the trace to some web service set up specifically to grab them. Using Google App Engine is excellent for this purpose since it already has a logging feature which grabs all kinds of meta data from the client calling the application. Also, if your logs become huge for some reason - at least you wont have to worry about storing them. Google does that for you :)
I've set up such a service as outlined below (granted it has some flaws, in particular anyone can call it and add "traces", but you could add some shared secret and post over HTTPS to have some tiny measure of security).
App Engine Logging Service
#!/usr/bin/env python
from google.appengine.ext import webapp
from google.appengine.ext.webapp import util
class MainHandler(webapp.RequestHandler):
def post(self):
import logging
if self.request.get('trace'):
logging.error(self.request.get('trace')) #Adds a row to GAE:s own logs :)
self.response.out.write('trace logged')
else:
set_status(501)
def get(self):
""" Kill this function when done testing """
test_form = """
<form action="/" method="POST">
<textarea name="trace"></textarea>
<input type="submit">
</form>"""
self.response.out.write(test_form)
def main():
application = webapp.WSGIApplication([('/', MainHandler)],
debug=False)
util.run_wsgi_app(application)
if __name__ == '__main__':
main()
I wrote a little AIR-app containing this little test function which simply POST:ed the app engine service with the parameter "trace" specified.
Posting to the logging service (ActionScript)
private function postToLogger(event:MouseEvent):void
{
var service:HTTPService = new HTTPService();
var parameters:Object = {'trace': "omg something went wrong"};
service.url = "https://YOURSUPERSIMPLELOGGINGSERVICE.APPSPOT.COM";
service.method = HTTPRequestMessage.POST_METHOD;
service.resultFormat = HTTPService.RESULT_FORMAT_E4X;
service.addEventListener("result", onSuccess);
service.addEventListener("fault", onError);
service.send(parameters);
}
And finally, this is how it looks in the logs, lots of metadata, and of the trace you caught in your AIR app.

Resources