bypassing auto-discovery -- seems not quite right

14 views
Skip to first unread message

Dewey Gaedcke

unread,
Feb 26, 2016, 2:20:05 PM2/26/16
to Ferris Framework
Given the directory structure suggested, I'm bypassing F3 auto-discovery as follows

# main.py  (inside of one microservice)


from ferris3 import endpoints
import endpoints as google_cloud_endpoints
from person_service import PersonService   # this uses the F3 auto-service and auto-method annotations


# PersonService looks like:
# @auto_service(endpoint='person')
# class PersonService(Service):
#
#     get = hvild.get(Person)


endpoints
.add('backend-endpoint.yaml', default=True)


# backend-endpoint.yaml looks like:
# canonical_name: Backend API
# name: backend
# version: v1
# description: API for mobile apps
# auth_level: optional
# scopes:
# - USERINFO
# allowed_client_ids:
# - API_EXPLORER_CLIENT_ID
# - 11585xxxx03-lkadkljsdlkjdsfkjeer.apps.googleusercontent.com


# APIs
API_CLASSES
= [PersonService]

app
= google_cloud_endpoints.api_server(API_CLASSES)

and it doesn't seem quite right.....
since "backend-endpoint.yaml" is being loaded AFTER PersonService (which declares the services)
I can't see how the "person" endpoint will get bound to the "backend" endpoint config....

I think I'm still missing something??
Thanks again for all the support!


Dewey Gaedcke

unread,
Feb 26, 2016, 2:31:48 PM2/26/16
to Ferris Framework
I think by writing that question, I figured it out myself:

import endpoints_config     # establishes the endpoint 'backend' in registry w defaults
# now import all the classes that expose endpoint services under "endpoint=backend"
from person_service import PersonService

import endpoints as google_cloud_endpoints

# service APIs
API_CLASSES = [PersonService]
# bind to the endpoint infrastructure & return the app
app = google_cloud_endpoints.api_server(API_CLASSES)


Jonathan Parrott

unread,
Feb 26, 2016, 3:59:41 PM2/26/16
to Dewey Gaedcke, Ferris Framework
Glad you got it figured out. :)

Dewey Gaedcke

unread,
Feb 26, 2016, 5:16:08 PM2/26/16
to Ferris Framework, de...@pathoz.com
Well.....I thought I did

But api explorer --->>>

is logging a 302 (redirect) and not showing any API's to browse.....

Seems like my API is not discoverable for some reason....

Jonathan Parrott

unread,
Feb 26, 2016, 5:37:55 PM2/26/16
to Dewey Gaedcke, Ferris Framework
Probably the long-standing https issue. I think there's another thread in this forum on that.

Dewey Gaedcke

unread,
Feb 26, 2016, 7:46:28 PM2/26/16
to Ferris Framework, de...@pathoz.com
I don't think that's the issue for two reasons:
1)  I posted the solution to that other thread.....see below
2)  it was working right until I refactored my project into multiple modules and wired endpoints manually

To Launch chrome with https security settings disabled:

/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --user-data-dir=test --unsafely-treat-insecure-origin-as-secure=http://localhost:60612


Any other thoughts about what i should check?

Jonathan Parrott

unread,
Feb 27, 2016, 2:27:42 PM2/27/16
to Dewey Gaedcke, Ferris Framework

Not at the moment. If you can make an isolated case and share it with us we may be able to help further.

Dewey Gaedcke

unread,
Feb 27, 2016, 3:29:46 PM2/27/16
to Ferris Framework, de...@pathoz.com
Out of respect for your time, I'll clarify where I think the docs could be improved and then your answer can be used for many rather than just my specific case.

If the following does not clarify my issue, I'll spin up a separate project to demo what I'm seeing.

The docs (to me) get a bit confusing once you abandon auto-discovery.

For example, under UserGuide.Defining Endpoints, you see these examples:

import ferris3

# Exposed as ferris.posts
@ferris3.auto_service
class PostsService(ferris3.Service):
   
...

# Exposed as ferris.photos
@ferris3.auto_service(name='photos')
class ImagesService(ferris3.Service):
   
...

# Exposed as mobile_only.photos
@ferris3.auto_service(name='photos', endpoint='mobile_only')
class ImagesApi(ferris3.Service):
   
...

Directly above these examples is this (slightly modified---I replaced "ferris" with "someEndpointName") YAML:
canonical_name: Ferris Endpoint
# API name. Should be lower case and only contain letters, numbers and underscores.
# Used in the client libraries, e.g. gapi.client.ferris.
name: someEndpointName

None of the "auto_service" examples above mention the word "someEndpointName"  (the actual endpoint name) and several even provide a (previously unseen) "name" argument that is different from any endpoints that have been previously created...  (as a note, "ferris" is a somewhat ambiguous name as it could imply some bind the the lbr)
This sentence attempts to clarify:

You can now use this endpoint by name (the name field in the yaml file) when defining services.

I'm assuming this means to specify f3.auto_servce(name="someEndpointName") but the 3rd example
@ferris3.auto_service(name='photos', endpoint='mobile_only')

seems to contradict the above sentence because it uses an (also new) "endpoint" argument (mobile_only) so I'm not clear whether my service declarations should look like:
@auto_service(name='someEndpointName')
or
@auto_service(endpoint='someEndpointName', name='person')
or
@auto_service(resource_name='someEndpointName', name='person')

Thanks for feedback!
Dewey


Dewey Gaedcke

unread,
Feb 27, 2016, 3:45:14 PM2/27/16
to Ferris Framework, de...@pathoz.com
In addition to the above feedback, considering this example:
# Exposed as ferris.posts
@ferris3.auto_service
class PostsService(ferris3.Service):

I would also clarify how:
  1. auto_service knows which endpoint this class is being attached to (ie presumably ferris in this case)
  2. the "posts" route-element gets added (I'm assuming by the directory structure but what if you're NOT using auto-discovery)

Dewey Gaedcke

unread,
Feb 28, 2016, 10:19:35 AM2/28/16
to Ferris Framework, de...@pathoz.com
Ok, I'm still stuck.....here's my entire setup.
I've tried to make it generic enough to be useful to others who use multiple modules and thus forsake auto-discovery

appengine_config.py
import vendor
vendor
.add('lib')


service_backend.yaml
# service_backend for full client API
module: backend
application
: testproject
runtime
: python27
threadsafe
: true
api_version
: 1


handlers
:
# Endpoints handler
- url: /_ah/spi/.*
  script
: service_backend.main.app
 
# optional, always, never
  secure
: optional
 
# login: admin


libraries
:
- name: pycrypto
  version
: latest
- name: endpoints
  version
: 1.0

service_backend/main.py

import endpoints_config     # establishes the endpoint 'backend' in registry w defaults (see below)
import endpoints as google_cloud_endpoints
import ferris3 as f3

from person_service import PersonService   # this loads endpoint classes  (see below)
backendEndpoint = f3.endpoints.get('backend')

# service APIs
API_CLASSES = [backendEndpoint]
# bind to the endpoint infrastructure & return the app
app = google_cloud_endpoints.api_server(API_CLASSES)

service_backend/endpoints_config.py
from ferris3 import endpoints
endpoints.add('service_backend/backend-endpoint.yaml', default=True)


 service_backend/person_service.py
# some boilerplate imports up here
import ferris3 as f3
from common.models.person_model import Person

# experimenting:  next 2 lines may be unnecessary with Ferris3
# with straight google endpoints I would need one of these as my decorators for classes below
endpoint = f3.endpoints.default()
backendEndpoint = f3.endpoints.get('backend')

# some message structures declared here

@auto_service(endpoint='backend', resource_name='person')
class PersonService(Service):
    get = hvild.get(Person)


To start it all, I run:
dev_appserver.py service_backend.yaml 
And I see:

INFO     2016-02-28 14:56:53,316 sdk_update_checker.py:229] Checking for updates to the SDK.

INFO     2016-02-28 14:56:53,567 api_server.py:205] Starting API server at: http://localhost:55078

INFO     2016-02-28 14:56:53,571 dispatcher.py:197] Starting module "backend" running at: http://localhost:8080

INFO     2016-02-28 14:56:53,573 admin_server.py:116] Starting admin server at: http://localhost:8000

WARNING  2016-02-28 14:56:53,573 devappserver2.py:835] No default module found. Ignoring.

INFO     2016-02-28 14:57:12,811 module.py:787] backend: "GET /_ah/api/explorer HTTP/1.1" 302


/api/explorer works with my old (non module/services based) code but shows no endpoints with the above setup.

All feedback welcome! 

Jonathan Parrott

unread,
Feb 29, 2016, 11:21:18 PM2/29/16
to Dewey Gaedcke, Ferris Framework
Hey Dewey, it would be a bit easier for me to reproduce if you could share this via github - either a repo or a gist with everything.

Dewey Gaedcke

unread,
Feb 29, 2016, 11:31:49 PM2/29/16
to Ferris Framework, de...@pathoz.com
Oh your timing is good!!  ;-)
I just got it working.....was a missing import on my part so the services were not getting registered.

Thanks for looking at it!

And I'd be happy to edit the docs if you feel that my ideas would be useful.....

Jonathan Parrott

unread,
Feb 29, 2016, 11:32:54 PM2/29/16
to Dewey Gaedcke, Ferris Framework
Feel free to send PRs for your docs updates. i'm happy to review and merge. :)
Reply all
Reply to author
Forward
0 new messages