Momentan bin ich dabei mit AI2 eine App zu entwickeln und wollte dafür einen online Speicher haben. Aber jedes mal wenn ich auf "Deploy" klicke kommt nur diese Fehlermeldung:
2017-08-26 21:27:54 Running command: "['C:\\Python27\\python.exe', '-u', 'C:\\Program Files (x86)\\Google\\google_appengine\\appcfg.py', '--oauth2_credential_file=C:\\Users\\Passi/.appcfg_oauth2_tokens', 'update', 'E:\\customtinywebdb\\customtinywebdb']" 09:27 PM Application: test-178018; version: 1 09:27 PM Host: appengine.google.com 09:27 PM Starting update of app: test-178018, version: 1 09:27 PM Getting current resource limits. 09:27 PM Scanning files on local disk. Error 400: --- begin server output --- Python 2.5 is not supported in 'e' partition. --- end server output --- 2017-08-26 21:27:59 (Process exited with code 1) You can close this window now. Ich werde daraus nicht schlau, vor allem weil auf einmal irgendwas mit Python 2.5 da drin ist, obwohl ich nur Version 2.7 habe. Vielleicht hängt das damit zusammen, dass ich vorher einen anderen Fehler behoben hab, indem ich was weggenommen habe? 2017-08-26 21:15:23 Running command: "['C:\\Python27\\python.exe', 'C:\\Program Files (x86)\\Google\\google_appengine\\dev_appserver.py', '--skip_sdk_update_check=yes', '--port=8080', '--admin_port=8000', 'E:\\customtinywebdb\\customtinywebdb']" WARNING 2017-08-26 21:15:25,871 application_configuration.py:189] The "python" runtime specified in "E:\customtinywebdb\customtinywebdb\app.yaml" is not supported - the "python27" runtime will be used instead. A description of the differences between the two can be found here: https://developers.google.com/appengine/docs/python/python25/diff27 INFO 2017-08-26 21:15:25,871 devappserver2.py:116] Skipping SDK update check. INFO 2017-08-26 21:15:26,098 api_server.py:313] Starting API server at: http://localhost:51240 INFO 2017-08-26 21:15:26,102 dispatcher.py:226] Starting module "default" running at: http://localhost:8080 INFO 2017-08-26 21:15:26,104 admin_server.py:116] Starting admin server at: http://localhost:8000 INFO 2017-08-26 21:16:11,234 module.py:416] [default] Detected file changes: main.py INFO 2017-08-26 19:17:35,193 stubs.py:50] Sandbox prevented access to file "E:\customtinywebdb\customtinywebdb\main.pyc" INFO 2017-08-26 19:17:35,194 stubs.py:51] If it is a static file, check that `application_readable: true` is set in your app.yaml ERROR 2017-08-26 19:17:35,315 cgi.py:122] Traceback (most recent call last): File "E:\customtinywebdb\customtinywebdb\main.py", line 18, in <module> from django.utils import simplejson as json ImportError: No module named django.utils INFO 2017-08-26 21:17:35,326 module.py:832] default: "GET / HTTP/1.1" 500 - INFO 2017-08-26 21:17:55,250 module.py:416] [default] Detected file changes: main.py INFO 2017-08-26 21:18:01,153 api_server.py:945] Applying all pending transactions and saving the datastore INFO 2017-08-26 21:18:01,153 api_server.py:948] Saving search indexes 2017-08-26 21:18:01 (Process exited with code 0) 2017-08-26 21:18:02 Running command: "['C:\\Python27\\python.exe', 'C:\\Program Files (x86)\\Google\\google_appengine\\dev_appserver.py', '--skip_sdk_update_check=yes', '--port=8080', '--admin_port=8000', 'E:\\customtinywebdb\\customtinywebdb']" WARNING 2017-08-26 21:18:04,263 application_configuration.py:189] The "python" runtime specified in "E:\customtinywebdb\customtinywebdb\app.yaml" is not supported - the "python27" runtime will be used instead. A description of the differences between the two can be found here: https://developers.google.com/appengine/docs/python/python25/diff27 INFO 2017-08-26 21:18:04,263 devappserver2.py:116] Skipping SDK update check. INFO 2017-08-26 21:18:04,536 api_server.py:313] Starting API server at: http://localhost:51354 INFO 2017-08-26 21:18:04,539 dispatcher.py:226] Starting module "default" running at: http://localhost:8080 INFO 2017-08-26 21:18:04,540 admin_server.py:116] Starting admin server at: http://localhost:8000 INFO 2017-08-26 19:18:09,944 stubs.py:50] Sandbox prevented access to file "E:\customtinywebdb\customtinywebdb\main.pyc" INFO 2017-08-26 19:18:09,944 stubs.py:51] If it is a static file, check that `application_readable: true` is set in your app.yaml INFO 2017-08-26 21:18:10,078 module.py:832] default: "GET / HTTP/1.1" 200 2401 INFO 2017-08-26 21:18:10,118 module.py:832] default: "GET /images/customLogo.gif HTTP/1.1" 304 - INFO 2017-08-26 21:26:38,720 api_server.py:945] Applying all pending transactions and saving the datastore INFO 2017-08-26 21:26:38,720 api_server.py:948] Saving search indexes 2017-08-26 21:26:39 (Process exited with code 0) 2017-08-26 21:30:22 Running command: "['C:\\Python27\\python.exe', 'C:\\Program Files (x86)\\Google\\google_appengine\\dev_appserver.py', '--skip_sdk_update_check=yes', '--port=8080', '--admin_port=8000', 'E:\\customtinywebdb\\customtinywebdb']" WARNING 2017-08-26 21:30:24,914 application_configuration.py:189] The "python" runtime specified in "E:\customtinywebdb\customtinywebdb\app.yaml" is not supported - the "python27" runtime will be used instead. A description of the differences between the two can be found here: https://developers.google.com/appengine/docs/python/python25/diff27 INFO 2017-08-26 21:30:24,914 devappserver2.py:116] Skipping SDK update check. INFO 2017-08-26 21:30:25,115 api_server.py:313] Starting API server at: http://localhost:51495 INFO 2017-08-26 21:30:25,119 dispatcher.py:226] Starting module "default" running at: http://localhost:8080 INFO 2017-08-26 21:30:25,121 admin_server.py:116] Starting admin server at: http://localhost:8000 INFO 2017-08-26 19:30:29,503 stubs.py:50] Sandbox prevented access to file "E:\customtinywebdb\customtinywebdb\main.pyc" INFO 2017-08-26 19:30:29,503 stubs.py:51] If it is a static file, check that `application_readable: true` is set in your app.yaml ERROR 2017-08-26 19:30:29,618 cgi.py:122] Traceback (most recent call last): File "E:\customtinywebdb\customtinywebdb\main.py", line 18, in <module> from django.utils import simplejson as json ImportError: No module named django.utils INFO 2017-08-26 21:30:29,628 module.py:832] default: "GET / HTTP/1.1" 500 - Diese Fehlermeldung kam immer, wenn ich auf localhost:8080 gegangen bin, aber seid dem ich in der anhängenden Datei Zeile 18 (from django.utils import simplejson as json) entfernt habe, hat das funktioniert. Allerdings bringt mir ja ein localhost nichts, wenn die App für alle zugägnlich sein soll^^. Würde mich sehr freuen wenn mir wer helfen könnte :) Lg Pascal -- You received this message because you are subscribed to the Google Groups "Google App Engine" group. To unsubscribe from this group and stop receiving emails from it, send an email to google-appengine+unsubscr...@googlegroups.com. To post to this group, send email to google-appengine@googlegroups.com. Visit this group at https://groups.google.com/group/google-appengine. To view this discussion on the web visit https://groups.google.com/d/msgid/google-appengine/6d75602b-9d8b-442c-8e35-5820e3b58fa8%40googlegroups.com. For more options, visit https://groups.google.com/d/optout.
#!/usr/bin/env python ### ### This is a web service for use with App ### Inventor for Android (<http://appinventor.googlelabs.com>) ### This particular service stores and retrieves tag-value pairs ### using the protocol necessary to communicate with the TinyWebDB ### component of an App Inventor app. ### Author: David Wolber (wol...@usfca.edu), using sample of Hal Abelson import logging from cgi import escape from google.appengine.ext import webapp from google.appengine.ext.webapp.util import run_wsgi_app from google.appengine.ext import db from google.appengine.ext.db import Key from django.utils import simplejson as json class StoredData(db.Model): tag = db.StringProperty() value = db.StringProperty(multiline=True) ## defining value as a string property limits individual values to 500 ## characters. To remove this limit, define value to be a text ## property instead, by commnenting out the previous line ## and replacing it by this one: ## value db.TextProperty() date = db.DateTimeProperty(required=True, auto_now=True) IntroMessage = ''' <table border=0> <tr valign="top"> <td><image src="/images/customLogo.gif" width="200" hspace="10"></td> <td> <p> This web service is designed to work with <a href="http://appinventor.googlelabs.com">App Inventor for Android</a> and the TinyWebDB component. The end-goal of this service is to communicate with a mobile app created with App Inventor. </p> The page your are looking at is a web page interface to the web service to help programmers with debugging. You can invoke the get and store operations by hand, view the existing entries, and also delete individual entries.</p> </td> </tr> </table>''' class MainPage(webapp.RequestHandler): def get(self): write_page_header(self); self.response.out.write(IntroMessage) write_available_operations(self) show_stored_data(self) self.response.out.write('</body></html>') ######################################## ### Implementing the operations ### Each operation is design to respond to the JSON request ### or to the Web form, depending on whether the fmt input to the post ### is json or html. ### Each operation is a class. The class includes the method that ### actually, manipualtes the DB, followed by the methods that respond ### to post and to get. class StoreAValue(webapp.RequestHandler): def store_a_value(self, tag, value): # There's a potential readers/writers error here :( entry = db.GqlQuery("SELECT * FROM StoredData where tag = :1", tag).get() if entry: entry.value = value else: entry = StoredData(tag = tag, value = value) entry.put() ## Send back a confirmation message. The TinyWebDB component ignores ## the message (other than to note that it was received), but other ## components might use this. result = ["STORED", tag, value] WritePhoneOrWeb(self, lambda : json.dump(result, self.response.out)) def post(self): tag = self.request.get('tag') value = self.request.get('value') self.store_a_value(tag, value) def get(self): self.response.out.write(''' <html><body> <form action="/storeavalue" method="post" enctype=application/x-www-form-urlencoded> <p>Tag<input type="text" name="tag" /></p> <p>Value<input type="text" name="value" /></p> <input type="hidden" name="fmt" value="html"> <input type="submit" value="Store a value"> </form></body></html>\n''') class GetValue(webapp.RequestHandler): def get_value(self, tag): entry = db.GqlQuery("SELECT * FROM StoredData where tag = :1", tag).get() if entry: value = entry.value else: value = "" ## We tag the returned result with "VALUE". The TinyWebDB ## component makes no use of this, but other programs might. ## check if it is a html request and if so clean the tag and value variables if self.request.get('fmt') == "html": value = escape(value) tag = escape(tag) WritePhoneOrWeb(self, lambda : json.dump(["VALUE", tag, value], self.response.out)) def post(self): tag = self.request.get('tag') self.get_value(tag) def get(self): self.response.out.write(''' <html><body> <form action="/getvalue" method="post" enctype=application/x-www-form-urlencoded> <p>Tag<input type="text" name="tag" /></p> <input type="hidden" name="fmt" value="html"> <input type="submit" value="Get value"> </form></body></html>\n''') ### The DeleteEntry is called from the Web only, by pressing one of the ### buttons on the main page. So there's no get method, only a post. class DeleteEntry(webapp.RequestHandler): def post(self): logging.debug('/deleteentry?%s\n|%s|' % (self.request.query_string, self.request.body)) entry_key_string = self.request.get('entry_key_string') key = db.Key(entry_key_string) tag = self.request.get('tag') db.run_in_transaction(dbSafeDelete,key) self.redirect('/') ######################################## #### Procedures used in displaying the main page ### Show the API def write_available_operations(self): self.response.out.write(''' <p>Available calls:\n <ul> <li><a href="/storeavalue">/storeavalue</a>: Stores a value, given a tag and a value</li> <li><a href="/getvalue">/getvalue</a>: Retrieves the value stored under a given tag. Returns the empty string if no value is stored</li> </ul>''') ### Generate the page header def write_page_header(self): self.response.headers['Content-Type'] = 'text/html' self.response.out.write(''' <html> <head> <style type="text/css"> body {margin-left: 5% ; margin-right: 5%; margin-top: 0.5in; font-family: verdana, arial,"trebuchet ms", helvetica, sans-serif;} ul {list-style: disc;} </style> <title>Tiny WebDB</title> </head> <body>''') self.response.out.write('<h2>App Inventor for Android: Custom Tiny WebDB Service</h2>') ### Show the tags and values as a table. def show_stored_data(self): self.response.out.write(''' <p><table border=1> <tr> <th>Key</th> <th>Value</th> <th>Created (GMT)</th> </tr>''') # This next line is replaced by the one under it, in order to help # protect against SQL injection attacks. Does it help enough? #entries = db.GqlQuery("SELECT * FROM StoredData ORDER BY tag") entries = StoredData.all().order("-tag") for e in entries: entry_key_string = str(e.key()) self.response.out.write('<tr>') self.response.out.write('<td>%s</td>' % escape(e.tag)) self.response.out.write('<td>%s</td>' % escape(e.value)) self.response.out.write('<td><font size="-1">%s</font></td>\n' % e.date.ctime()) self.response.out.write(''' <td><form action="/deleteentry" method="post" enctype=application/x-www-form-urlencoded> <input type="hidden" name="entry_key_string" value="%s"> <input type="hidden" name="tag" value="%s"> <input type="hidden" name="fmt" value="html"> <input type="submit" style="background-color: red" value="Delete"></form></td>\n''' % (entry_key_string, escape(e.tag))) self.response.out.write('</tr>') self.response.out.write('</table>') #### Utilty procedures for generating the output #### Write response to the phone or to the Web depending on fmt #### Handler is an appengine request handler. writer is a thunk #### (i.e. a procedure of no arguments) that does the write when invoked. def WritePhoneOrWeb(handler, writer): if handler.request.get('fmt') == "html": WritePhoneOrWebToWeb(handler, writer) else: handler.response.headers['Content-Type'] = 'application/jsonrequest' writer() #### Result when writing to the Web def WritePhoneOrWebToWeb(handler, writer): handler.response.headers['Content-Type'] = 'text/html' handler.response.out.write('<html><body>') handler.response.out.write(''' <em>The server will send this to the component:</em> <p />''') writer() WriteWebFooter(handler, writer) #### Write to the Web (without checking fmt) def WriteToWeb(handler, writer): handler.response.headers['Content-Type'] = 'text/html' handler.response.out.write('<html><body>') writer() WriteWebFooter(handler, writer) def WriteWebFooter(handler, writer): handler.response.out.write(''' <p><a href="/"> <i>Return to Game Server Main Page</i> </a>''') handler.response.out.write('</body></html>') ### A utility that guards against attempts to delete a non-existent object def dbSafeDelete(key): if db.get(key) : db.delete(key) ### Assign the classes to the URL's application = \ webapp.WSGIApplication([('/', MainPage), ('/storeavalue', StoreAValue), ('/deleteentry', DeleteEntry), ('/getvalue', GetValue) ], debug=True) def main(): run_wsgi_app(application) if __name__ == '__main__': main() ### Copyright 2009 Google Inc. ### ### Licensed under the Apache License, Version 2.0 (the "License"); ### you may not use this file except in compliance with the License. ### You may obtain a copy of the License at ### ### http://www.apache.org/licenses/LICENSE-2.0 ### ### Unless required by applicable law or agreed to in writing, software ### distributed under the License is distributed on an "AS IS" BASIS, ### WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ### See the License for the specific language governing permissions and ### limitations under the License. ###