Python 2.7 App executing as CGI instead of WSGI on App Engine - google-app-engine

The following code generates a CGI method instead of WSGI as indicated in the log below. Is this the normal execution for a WSGI app on the dev server? If not what needs to change to get the application to execute as WSGI?
main.py
import webapp2
import wsgiref.handlers
import logging
from google.appengine.api import users
class HomeHandler(webapp2.RequestHandler):
def get(self):
self.response.out.write("Hi World")
app = webapp2.WSGIApplication([
(r'/', HomeHandler),
], debug=True)
app.run()
app.yaml
application: WSGITEST
version: 1
runtime: python27
api_version: 1
threadsafe: yes
libraries:
- name: webapp2
version: latest
handlers:
- url: /.*
script: main.app
Log
DEBUG 2012-05-09 21:31:14,921 dev_appserver.py:656] Matched "/" to CGI dispatcher with path main.app
DEBUG 2012-05-09 21:31:14,926 dev_appserver_import_hook.py:1246] Enabling webapp2: None
DEBUG 2012-05-09 21:31:14,928 dev_appserver.py:1624] Executing CGI with env:
{'REQUEST_ID_HASH': '77DE68DA', 'SERVER_SOFTWARE': 'Development/1.0', 'SCRIPT_NAME': '', 'REQUEST_METHOD': 'GET', 'PATH_INFO': '/', 'SERVER_PROTOCOL': 'HTTP/1.0', 'QUERY_STRING': '', 'CONTENT_LENGTH': '', 'USER_ID': '', 'APPENGINE_RUNTIME': 'python27', 'TZ': 'UTC', 'SERVER_NAME': 'localhost', 'REMOTE_ADDR': '127.0.0.1', 'SDK_VERSION': '1.6.5', 'PATH_TRANSLATED': '/home/bear/dev/appengine/code/ae-baseapp/401/main3.app', 'SERVER_PORT': '8080', '_AH_THREADSAFE': '1', 'CURRENT_VERSION_ID': '1.1', 'USER_ORGANIZATION': '', 'HTTP_USER_AGENT': 'Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:12.0) Gecko/20100101 Firefox/12.0', 'HTTP_HOST': 'localhost:8080', 'HTTP_CONNECTION': 'keep-alive', 'USER_EMAIL': '', 'HTTP_ACCEPT': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 'APPLICATION_ID': 'dev~WSGITEST', 'GATEWAY_INTERFACE': 'CGI/1.1', 'HTTP_ACCEPT_LANGUAGE': 'en-us,en;q=0.5', 'HTTP_DNT': '1', 'CONTENT_TYPE': 'application/x-www-form-urlencoded', '_AH_ENCODED_SCRIPT_NAME': '/', 'AUTH_DOMAIN': 'gmail.com'}
INFO 2012-05-09 21:31:14,933 dev_appserver.py:2891] "GET / HTTP/1.1" 200 -

this log is a hardcoded string:
/usr/local/google_appengine/google/appengine/tools/dev_appserver.py:
1622 sys.modules['__builtin__'] = __builtin__
1623
1624: logging.debug('Executing CGI with env:\n%s', repr(env))

First, you should remove this line of code because it's incorrect:
app.run()
As written in my comment and well pointed out by aschmid00, could be an old debug statement.

Related

SocketIo behind traefik and reverse proxy. Unable to connect

I am unable to connect to socketio in production.
This is my traefik file. my backend gets all calls which go to /api....
backend:
build:
context: ./backend
dockerfile: Dockerfile
command: ["npm", "run", "start"]
labels:
- "traefik.enable=true"
- "traefik.http.routers.backend.rule=Host(`mydomain.com`) && PathPrefix(`/api`)"
networks:
- web
My express server:
export const io = new Server(server, {
cors: {
origin: [
"http://localhost:5173",
"https://mysecretdomain.com",
],
},
});
My react frontend:
let socket: any;
if (import.meta.env.MODE === 'development') {
socket = io(API_CONFIGS.SOCKET_IO_URL);
} else {
// the app runs with traefik and is available under the prefix /api
socket = io(API_CONFIGS.SOCKET_IO_URL, { path: '/api/socket.io' });
}
In Development, everything works fine but in prod im getting a 404 error
example call from my domain
https://mysecretdomain/api/socket.io/?EIO=4&transport=polling&t=OKSmUX8
Status:404
I am completly out of ideas. Can someone help me out?

Use name of Docker (Flask) service inside package.json of React app

I'm trying to have my React front end application interact with a Flask API, both Dockerized and built together with docker-compose. Here is the docker-compose.yml file:
version: "3.9"
services:
server:
build: ./server
ports:
- "80:5000"
volumes:
- ./server:/app
environment:
FLASK_ENV: development
env_file:
- ./.env
web:
build: ./app
ports:
- "3000:3000"
volumes:
- ./app:/user/src/app
depends_on:
- server
The package.json looks like this:
{
"name": "housing",
"version": "0.1.0",
"private": true,
...
"proxy":"http://server:80"
}
And then in App.js file trying to call the API with:
callAPI( some_arg ) {
var h = new Headers();
h.append("Content-Type", "application/json");
h.append("Access-Control-Allow-Origin", "*");
var raw = JSON.stringify({"some_arg":some_arg});
var requestOptions = {
method: 'POST',
headers: h,
body: raw,
redirect: 'follow'
};
const url = '/api/some_service'
fetch(url, requestOptions).then(res => res.json()).then(data => {
this.setState({some_component_data: data});
});
}
Unfortunately doing this results in an error:
Proxy error: Could not proxy request /api/some_service from localhost:3000 to http://server:80.
It works fine if I replace server with 0.0.0.0 but I'd quite like to use the actual container name in package.json. How can I do this?
My use case is a little different (django + redis), but I would try some combination of these 2 things:
Remove the http:// and just use server:80
Specify container_name in your docker-compose file. I don't know if this is actually necessary or if it uses the service name to connect, but worth a shot if the first thing doesn't work alone.
For my use case, the connection string is just redis://redis and the docker-compose section for that service looks like this:
redis:
image: redis
container_name: redis
restart: always
command: redis-server --requirepass <password>
volumes:
- redis_data:/data
ports:
- "6379:6379"

websocket_handshake_failed on GCP Cloud http load balancer with 403 response

We are getting thousands of websocket_handshake_failed on our GCP load balancer.
Our Environment is: App Engine Flex environment with auto-scale + Postgress cloud SQL
we have a chat SaaS application so we use sockets.
on the logging, I see +1000 websocket_handshake_failed each hour,
below is the sample of the log of a single error:
{
insertId: "1yr7yf8g129xnqm"
jsonPayload: {2}
httpRequest: {
requestMethod: "GET"
requestUrl: "https://platform.businesschat.io/socket/websocket?auth_token=SFMyNTY.g2gDdAAAAAFkAAd1c2VyX2lkYR5uBgBpppTkeAFiAAFRgA.KRJF8oZWOOtsOS0aqNUzf8OJgip-znonz31WSPGwUlQ&vsn=2.0.0"
requestSize: "2382"
status: 403
responseSize: "231"
userAgent: "Mozilla/5.0 (Macintosh; Intel Mac OS X 11_2_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.114 Safari/537.36"
remoteIp: "188.54.82.167"
serverIp: "10.156.0.30"
}
resource: {
type: "http_load_balancer"
labels: {
target_proxy_name: ""
url_map_name: ""
project_id: "businesschat-platform"
forwarding_rule_name: ""
backend_service_name: "aef-default-20210418t185059-bs"
zone: "global"
}
}
timestamp: "2021-04-19T10:05:16.050343Z"
severity: "WARNING"
logName: "projects/businesschat-platform/logs/requests"
trace: "projects/businesschat-platform/traces/2205a954ba0c5d518574a6b00316fa92"
receiveTimestamp: "2021-04-19T10:05:17.924136122Z"
spanId: "692567857ac6b22b"
}
on the front end, Am getting a sample connection: close error, not sure if that is related:

Google appengine cloud tasks alpha handler http 404 error

When I send a task to a task queue it keeps failing and shows a http 404 (not found) error in the logs.
The project has been whitelisted for cloud tasks alpha on flexible.
I can send HTTP post requests to /endpointpath & /tasks/worker locally without any errors.
The endpoint works fine and adds the task to the task queue.
13:37:41.300 POST 200 0 B 422 ms curl/7.54.0 /endpointspath?key=keyremoved 0.0.0.0 - "POST endpointspath?key=keyremoved" 200 undefined "-" "curl/7.54.0"
The app is running as the default service.
app.go main func:
func main() {
r := mux.NewRouter()
r.HandleFunc("/", handler)
r.HandleFunc("/_ah/health", healthCheckHandler)
// Task handlers
r.Path("/tasks/worker").Methods("POST", "GET", "PUT").HandlerFunc(workerTaskHandler)
// Endpoints
r.Path("/endpointpath").Methods("POST").HandlerFunc(searchHandler)
http.Handle("/", r)
port := 8080
if portStr := os.Getenv("PORT"); portStr != "" {
port, _ = strconv.Atoi(portStr)
}
log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", port), nil))
}
abbreviated app.yaml:
runtime: go
env: flex
handlers:
- url: /tasks/.*
script: _go_app
- url: /.*
script: _go_app
Logs HTTP 404 response when queue dispatches request to worker:
10.0.0.1 - "POST /tasks/worker" 404 200 "-" "AppEngine-Google; (+http://code.google.com/appengine)"
Expand all | Collapse all {
httpRequest: {
latency: "0s"
referer: "-"
remoteIp: "10.0.0.1"
requestMethod: "POST"
requestUrl: "/tasks/worker"
responseSize: "200"
status: 404
userAgent: "AppEngine-Google; (+http://code.google.com/appengine)"
}
insertId: "......."
jsonPayload: {
appLatencySeconds: "-"
latencySeconds: "0.000"
time: null
trace: "......."
}
labels: {
appengine.googleapis.com/instance_name: "......"
appengine.googleapis.com/trace_id: "......."
compute.googleapis.com/resource_id: "......."
compute.googleapis.com/resource_name: "......"
compute.googleapis.com/zone: "us-central1-b"
}
logName: "projects/projectname/logs/appengine.googleapis.com%2Fnginx.request"
receiveTimestamp: "2017-12-09T10:56:14.794726383Z"
resource: {
labels: {
module_id: "default"
project_id: "projectname"
version_id: "....."
}
type: "gae_app"
}
timestamp: "2017-12-09T10:56:10.301Z"
}
The closest I can get GAE to find the tasks/worker url is by setting login:admin in app.yaml (even tho flex doesn't use this for authentication). This returns a 403 unauthorised error.
handlers:
- url: /tasks/.*
script: _go_app
login: admin
Here is the 403 response in the logs
{
httpRequest: {
latency: "0s"
referer: "-"
remoteIp: "10.0.0.1"
requestMethod: "POST"
requestUrl: "/tasks/worker"
responseSize: "162"
status: 403
userAgent: "AppEngine-Google; (+http://code.google.com/appengine)"
}
insertId: "....."
jsonPayload: {
appLatencySeconds: "-"
latencySeconds: "0.000"
time: null
trace: "....."
}
labels: {
appengine.googleapis.com/instance_name: "...."
appengine.googleapis.com/trace_id: "...."
compute.googleapis.com/resource_id: "...."
compute.googleapis.com/resource_name: "....."
compute.googleapis.com/zone: "us-central1-b"
}
logName: "projects/projectname/logs/appengine.googleapis.com%2Fnginx.request"
receiveTimestamp: "2017-12-09T13:35:59.986118082Z"
resource: {
labels: {
module_id: "default"
project_id: "projectname"
version_id: "....."
}
type: "gae_app"
}
timestamp: "2017-12-09T13:35:54.764Z"
}
Not sure if it's related but projectname.appspot.com/_ah/health returns this error:
{
"code": 5,
"message": "Method does not exist.",
"details": [
{
"#type": "type.googleapis.com/google.rpc.DebugInfo",
"stackEntries": [],
"detail": "service_control"
}
]
}
It turns out endpoints can't run on the same service as task handlers. Task handler url requests are blocked by the ESP proxy if they run on the same service in the flexible environment, and the service has the endpoints service enabled.
Run task handlers on a separate service and do not set "endpoints_api_service:" in the task handler service app.yaml file.
Doing so will prevent the queue from being able to dispatch to workers in the flexible environment.
This isn't mentioned in the app engine documentation which is kinda bizarre.
The "/_ah/health" issue was caused by this path not being set in the open api file. If this path isn't set the url isn't recognised by the proxy.

Google App Engine WebApp2 template not working

I am learning Google App Engine, and have started with WebApp2 framework + Jinja2 template.
I have written the following code:
Main.py
import webapp2
import os
import jinja2
from google.appengine.ext.webapp import template
from google.appengine.api import users
from google.appengine.ext import ndb
template_dir = os.path.join(os.path.dirname(__file__), 'templates')
jinja_env = jinja2.Environment(loader = jinja2.FileSystemLoader(template_dir))
class Handler(webapp2.RequestHandler):
def write(self, *a, **kw):
self.response.out.write(*a, **kw)
def render_str(self, template, **params):
t = jinja_env.get_template(template)
return t.render(params)
def render(self, template, **kw):
self, write(self.render_str(template, **kw))
class MainHandler(webapp2.RequestHandler):
def get(self):
self.response.write('Hello world!')
class PageOne(Handler):
def get(self):
self.render('pageone.html')
app = webapp2.WSGIApplication([('/', MainHandler),('/pageone', PageOne)], debug=True)
app.yaml
application: tbapp
version: 1
runtime: python27
api_version: 1
threadsafe: yes
handlers:
- url: /favicon\.ico
static_files: favicon.ico
upload: favicon\.ico
- url: .*
script: main.app
libraries:
- name: webapp2
version: "2.5.2"
- name: jinja2
version: latest
There is also a pageone.html HTML file in templates folder.
Now, when I run the files, the main page is showing Hello world!. But, when I run http://localhost:8080/pageone..... it returns the following error..
File "E:\gae_apps\tbapp\tbapp\main.py", line 50, in get
self.render('pageone.html')
File "E:\gae_apps\tbapp\tbapp\main.py", line 40, in render
self, write(self.render_str(template, **kw))
NameError: global name 'write' is not defined
Can anyone please guide me, what am In doing wrong. I am not able to figure out. TIA
As Amber pointed out, you have a typo in your Handler's render method.
Replace
def render(self, template, **kw):
self, write(self.render_str(template, **kw))
With
def render(self, template, **kw):
self.write(self.render_str(template, **kw))
The error message does give you a hint
NameError: global name 'write' is not defined

Resources