GAE Namespace based on subdomain - python

I am considering a multi-tenant environment where I can have each tenant access a different subdomain and then potentially allocate a namespace based on that domain.
For instance,
tenantA.mydomain.com
tenantB.mydomain.com
Then I would want to have namespace tenantA for all tenantA data and tenantB for all tenantB data.
From the docs, it sounds like I would accomplish this in my appengine_config.py file and do something like this:
from google.appengine.api import namespace_manager
def namespace_manager_default_namespace_for_request():
this_namespace = get_namespace_from_subdomain()
return this_namespace
First question, is this a reasonable/good approach?
Second question, it's unclear what variables are available in this scope - any pointers on how to implement the get_namepsace_from_subdomain() function?
Finally, if there were some functionality I wanted to provide that would cross namespaces could this still be achieved with a global namespace? For instance, say a user has an account in multiple tenants and I want to give a view of his activity across all tenants.

It is possible and reasonable to use multi-tenancy in your app based on sub-domains, though from my experience you should also allow overriding the namespace by using a url param.
e.g.
tenantB.mydomain.com/?tenant=tenantA => namespace=tenantA
This will make you life a lot easier and will enable you to test your newest appengine versions on *.appspot.com before moving them to production (especially if you are planning on SSL access).
Once you set the namespace than only the entities under that namespace will be available, you can change the namespace via code whenever you want - the scope doesn't matter.
for the sub-domain - you can parse it out from the one of the client's request headers.
you can write whatever you want to the global namespace and access it whenever you want via code. for the scenario you described, you need to save the user activity on the global namespace.
also, take a loot at the official python example for using namespaces from the GAE team.
https://github.com/GoogleCloudPlatform/appengine-guestbook-namespaces-python
It gives you everything you need to get started.

I don't think this is the best approach to take. The problem with this approach is that you're tightly coupling you application with the infrastructure in a way. Domain and subdomain are just an easier way to access a machine bound to a specific ip address. I would classify domain names to be part of the infrastructure, not really part of the application. If you go with the above mentioned approach you're introducing some knowledge about the infrastructure into the application and thus making your application less flexible. What happens if you, for some reason, sometime in the future decide that your client A should use clientA.mydomain.com? or how about keyClientA.myotherdomain.com? Or how about you want to allow your client A to use their domain name, i.e. support.clientA.com? If your application does not know anything about domains and infrastructure setup then it's a lot easier to just reconfigure DNS server and get the portability.
If I had this scenario, I would have some kind of mapping of URLs to a tenant id, and then use that tenant id as a namespace name. This way you can easily map different URLs to a tenant id. You can even map multiple URLs to the same tenant id and expose the same application on multiple URLs. Your mapping can be stored in a simple config file or even in the AppEngine datastore itself within global namespace. If the config is stored in the AppEngine datastore, you can have your admin section of the application (or even another AppEngine module) which you can use to update config in real time.

Related

Hosting a multiple domains in pyramid

I am trying to design a SaaS app using pyramid. Clients will be able to design their facet of the app and their facet should be able to be served via the app.
To make things simpler to understand, let's say for example that we want to create an e-commerce SaaS app. The users should be able to create their own e-commerce site within the app and then access it with their own fqdn from the app if they wish.
I understand that we will need to address at least two issues and probably a third one:
Which fqdn the specific request is about.
How to distinguish static assets for each different fqdn.
How to connect to a different database for each fqdn.
Issue (1) can be easily addressed using request.domain (or request.host, request.host_url, etc.) as far as views and routes are concerned (I think). I am not sure, though, how I can address (2) and (3). The reason I am mentioning (3) is because I think that it's better to scale horizontally (having separate databases for each different fqdn) than vertically (having one database with huge tables/collections/whatevers containing data for all fqdns).
Moreover, let's keep in mind that our app should be able to live on a multiple-application-servers setup, which means that if configuration functions are needed to be called on one application server to e.g. update views dynamically, then the rest of the application servers hosting the same app should be able to be somehow informed about this configuration change as well.
Any ideas on how to resolve these issues (with an example, please) or any suggestions on how the architecture of this app could change to be more scalable and easy to develop are more than appreciated!
Thanks all in advance!
EDIT:
OK, I thought of a "hack" that generates different views for each different fqdn without using any static views in my configuration. I won't post the hack as a self reply yet, because it doesn't seem very elegant to me; but if I come with no better solutions and nobody proposes a better solution I'll post it :).
The general idea is to create a view (not a static view) that will serve our static paths with a *stararg (eg config.add_route('my_static_view', '/static/*subpaths') that will handle the static assets along with its route (eg. config.add_route('my_static_view', '/static')).
We will also need a static_view object within the same scope (let's call it static_view_obj) that will be used to serve our static content (we don't need to reinvent the wheel, we'll use pyramid's satic_view's functionality to serve our static assets). Within our my_static_view function we can alter static_view_obj's content to serve a different static path for each different request.domain.

Designing API for internal and remote usage in the Django app

I am starting web project that should be very flexible and modular and definitely will grow much in the future. As we plan to provide an api to other developers I started thinking that maybe it is a good idea to implement all the methods as api and provide functionality to use them remotely and internally.
For instance, say we want to extract all registered Users. So we design method in api, like get_all_users,which maybe available via REST or internal invocation. The problem is I cannot figure out how to distinguish access from internal usage and remote usage, as I should take into consideration also speed of internal invocation,code reusage and checking of user permissions(secret keys for api access, etc). What are the best practices? How to organize such API?
So to build the API, Tastypie or Piston. These let you write 'resources' (which are basically API versions of the views) - instead of returning httpresponses you just return objects which piston/tastypie convert into json or xml or yaml or whatever your favorite data-language is.
Securing the access: Consider decorating any resources which contain confidential information with the #login_required or #staff_member_required decorator as appropriate.
You might even want to go a step further and write a decorator to check that the staff user is using https (whereas you might allow a normal user to use any connection type).
If you have not considered it yet I recommend to use Tastypie to set up an API with django.
In order to distinguish between your internal and remote usage maybe you can simply design a different URL scheme.

How to create SaaS application with Python and Django

Can you advice me with some articles/applications that allows you create SaaS(Software as a Service) application with Python and Django.
For the moment the general topics I do not understand are:
Do you have one working application for all clients or one app per client
How do you manage database access, permissions or different DB for each client
Are there any tools that allows you to convert one app to SaaS
one project, this will make maintenance easier. I handle host resolution with middleware in django-ikari.
you don't. see #1
I use the following :
django-ikari : anchored (sub)domains
django-guardian : per object permissions
django-tastypie : easy RESTful api
django-userprofiles : better than django-registration
django-billing : plan based subscription controls
django-pricing : plan based subscription definition
While not necessary, the following will help in the long run:
django-hunger : private beta signups
django-waffle : feature flip
django-classy-tags : nice, easy and neat templatetag creation
django-merchant : abstracted payment gateway framework
django-mockups : fast testing with models
django-merlin : better multi-step forms (wizards)
Finally, nice to have
django-activity-stream
A very basic, elementary example of how you would go about it.
Suppose you have a simple app designed to solve a particular business case. For example, you created an app to handle room reservations at your office.
To "convert" this app into a service you have to configure it such that most of the user-specific parts of the application are parametric (they can be "templatized" - for lack of better word).
This is how the front end would be converted. You might create variables to hold the logo, headline, teaser, color scheme for the app; allowing each user to customize their instance.
So far, your app is able to customize itself on the front end. It is still using the same database that was designed in phase one.
Now comes the matter of showing only those fields that are relevant to a particular user. This would be parameterizing the database. So you might add a column that identifies each row as belonging to a particular user; then create views or stored procedures that filter records based on the logged in user.
Now the application is able to be "rented" out; since you are able to customize the instance based on the user.
It then just gets bigger from here - depending on the scale, type and intended customization of your application. You might decide that your application performs better when each user has their own dedicated database instead of the stored procedure + view combo.
You may decide that for some user types (or "packages"), you need a dedicated instance of your application running. So for "premium" or "ultra" users you want to have their own dedicated system running.
If your application requires lots of storage - you might decide to charge separately for storage.
The bottom line is it has nothing to do with the language used. Its more an architecture and design problem.
Software as a Service is just a marketing word, it's technically no different from a server that is accessible over the internet. So question 3 makes no sense. That leaves us with question 1 and 2:
What do you mean with 'app' in this context? Your web application (built with Python and Django) can have multiple Django apps (components that make up the web application) but I think that's not what you mean. You can build your website in Python/Django and have various customization options depending on which user (client) is logged in. For example, a premium client can have several advanced options enabled but it's still part of the same codebase. It's just that some options (buttons/controls, etc) are not shown for certain clients
Django has plenty of tools for user management, permissions and groups. You can give each user (each client) different permissions and these permissions determine what they can do. Database access should be managed by your web application. For example, the code determines what information needs to be displayed on the webpage (depending on which client is logged in) and that code retrieves the information from the database. Depending on the scale that you're aiming for, you can also specify which database should be used to retrieve the information from.
I have a blog post describing my proposal of how to go about making a multi tenant SAAS web application using Django. Multi-tenancy here means that when user registers, they have their sub-domain. To recap:
All tenants share one database, but each has their own schemas. Imagine you have website abc.com and someone registered a xyz tenant so that they access their page through xyz.abc.com, then for a tenant xyz you have a separate schema containing all the tables thus encapsulating data related only to xyz tenant. There are other ways, like having one database and one schema for all, or having even separate databases. But schemas approach is the best trade-off. The django-tenants library's documentation contains more detailed info if you are interested
Use django-tenants library to abstract away work with tenants. When someone accesses xyz.abc.com, you need to know that xyz is the tenant and that you should use xyz schema. django-tenants library does this for you so on each request you can obtain the tenant object by simply doing current_tenant = request.tenant
You need to differentiate between shared tables and tenant-specific tables. For example, having table with list of orders is tenant-specific. Every tenant might have their own database containing all their orders. This table should be inside xyz schema. At the same time, you will have some core Django tables, like user. The data can be shared, for example, to disallow two users registering with the same email.
You need to configure your DNS to catch a wildcard expression *.abc.com, for which you can add an A record inside your CPanel with *.abc.com linking to the IP of your server

Elegant way to make RPC Calls to Python Functions in a Django Project

I'm in the middle of trying to create a django website to access data in a MySQL database. The intenion is to also create a UI in Dojo (javascript). Also I would like the django backend to also provide webservices (RPC for python functions) to allow access to the MySQL database remotely. So for example, if someone wants to use Perl scripts to access the database (and possible other additional functionality like calculations based off of data in the database) they can do so in their native language (Perl).
Now ideally, the web services API is the same for javascript as well as another remote service that wants to access these services. I've found that JSON-RPC is a good way to go for this, as there is typically built in support for this in javascript in addition to the numerous additional benefits. Also a lot of people seem to be preferring SOAP to JSON.
I've seen several ways to do this:
1) Create a unique URI for each function that you would like to access:
https://code.djangoproject.com/wiki/JSONRPCServerMiddleware
2) Create one point of access, and pass the method name in the JSON package. In this particular example an SMD is automatically generated.
https://code.djangoproject.com/wiki/Jsonrpc
The issue with (1) is that if there are many functions to be accessed, then there will be many URI's that will be used. This does not seem like an elegant solution. The issue with (2) is that I need to compare functions against a list of all functions. Again this is not an elegant solution either.
Is there no way that we can take the advantages of (1) and (2) to create an interface such that:
- Only one URI is used as a point of access
- Functions are called directly (without having to be compared against a list of functions)
Any help with this will be really appreciated. Thanks!
what about using REST API?
One possibility to do the comparisons would be to use a dict like so:
def func1(someparams):
#do something
return True
def func2(sameparams):
#do something else
return True
{'func1': func1,
'func2': func2}
Then when you get the API call, you look it up in the dict and call from there, any function not in the dict would get the 404 handler.
It sounds like what you really want is a RPC server of some kind (SOAP, say, using soaplib) that is written in python and uses your application's data model, and what ever other APIs you have constructed to handle the business logic.
So I might implement the web service with soaplib, and have it call into the datamodel and other python modules as needed. People wanting to access your web application's data would use the SOAP service, but the web application would use the underlying datamodel + apis (for speed, your web app could use the SOAP service too, but it would be slower).

Managing subdomains

What are the best practices and solutions for managing dynamic subdomains in different technologies and frameworks? I am searching for something to implement in my Django project but those solutions that I saw, don't work. I also tried to use Apache rewrite mod to send requests from subdomain.domain.com to domain.com/subdomain but couldn't realize how to do it with Django.
UPDATE: What I need is to create virtual subdomains for my main domain using usernames from the site. So, if I have a new registered user that is called jack, when I go to jack.domain.com, it would operate make some operations. Like if I just went to domain.com/users/jack. But I don't want to create an actual subdomain for each user.
You may be able to do what you need with apache mod_rewrite.
Obviously I didn't read the question clearly enough.
As for how to do it in django: you could have some middleware that looks at the server name, and redirects according to that (or even sets a variable). You can't do it with the bare url routing system, as that only has path information, not hostname info.

Categories

Resources