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
Related
Currently in the company I have developed about six applications with Django, these applications are managed in different databases since they are focused on different departments. They are asking me that access to these applications be done through a single credential, that is, if a user must handle two applications, they should not have two different access credentials, but rather they can access both applications with a single credential.
I have consulted various sources, one person recommended me to develop an application that is only responsible for access, but I am a bit disoriented with this problem.
I appreciate the help!
I recently started developing a Desktop python application and I would like to know how more expert people would handle this issue.
I used to develop (about 5-10 years ago) web applications in the past using PHP + MySQL and there, since the code/program is located on the server where the user doesn't have access (except the web page), I could simply store the user/group permissions in the database in a table say users, users_groups, users_permissions, and so on. I would then check at every page load if the user had the right to access that page / update that record in the database.
With a desktop application where the user has access to the executable (which can relatively easy be decompiled to source code, being written in Python) the approach will likely be quite different.
Since MySQL has forked into MariaDB and is not so actively developed anymore, PostgreSQL looked promising to start. I thought about creating different users on PostgreSQL level and letting PostgreSQL handle the permissions (instad of my application handling them directly).
However, this only allows tuning of the permissions down to the table level. A user will be allowed to create/delete/update records in a table, however no further control is available. AFAIK you cannot tell "let this user only update his own records" or "this user can only delete the records from this group", or "users from group X can only update their own records while users from group Y can update everybody's records".
My understanding as how to handle this kind of issue would be to put some kind of middleware application between the user and the database, located on the server, such as:
Desktop application <-----> Server-side application permissions handler <-----> Database
Where server-side permission handler could be as simple as adding a "WHERE user=..." to each query as well as much more advanced stuff (first check user permissions stored in the database, based on that decide if letting user execute the query or reject it). I think this is a common problem for all desktop applications and would therefore expect that such a server-side application already exist. Am I missing something obvious or maybe PostgreSQL allows for more detailed fine-tuning?
Thank you for all your help ;)
Your intuition is right. It is never a good idea having a client access directly a database. Take a look a Django https://www.djangoproject.com and https://www.django-rest-framework.org
This would be the the basis for your server side. You would handle here business logic, authentication, authorization. The client should basically present the data within the UI and delegate all the decision making to the server.
Here you can find a step by step tutorial about how to implement a REST api with user authentication in Django. https://wsvincent.com/django-rest-framework-authentication-tutorial/
Is there software that provides multi-DB multi-tenant support for Django and works with MongoDB?
I think I only need multi-tenancy at the database level and maybe at the schema level but not at the application level.
I have a pretty complicated user model. Some users can view certain data inputted by other users. Users usually belong to organizations. Organizations can be nested hierarchically, and there can be similarities in how the application is configured for users within the organization (e.g., all users within an organization will fill out the same form, unless that's overriden for an individual user). Sometimes certain data that users submit can be viewed by users outside of their organization and even outside of the hierarchy that their organization's within. Organizations using the app can be competitors, and the data we're dealing with is sensitive, so it needs to be very secure. It also needs to be developed very quickly.
I'm thinking of giving each user their own DB, and then either having shared DBs or one shared DB with multiple schemas in order to store configurations that are shared across users within organizations.
Multi tenancy on MongoDB is perfectly viable, we are using it in production at onliquid.com.
I don't know of any lib, plugin or specific software that does it for you but it is doable with not that much effort. If you want to dive into it I would advise to pay special attention to how the driver you are using behaves when selecting the database to read and write to and start working on that. Also take a look at MongoDB configuration options like smallfiles and directoryperdb which allow you to better manage the differences and avoid some problems.
I wrote a blog post some time ago about this for Ruby on Rails using Mongoid, most of the details are applicable to all web frameworks and specific to the inner workings of MongoDB.
I'm in the process of building several Django based web applications for the same client. What I would like to do is set up an authentication server so that user credentials can be shared among django projects e.g. Jan Doe creates account for App-A and can use the same un and pw to log in to App-B.
Django packages is only somewhat helpful as I can't tell from the package descriptions if the package will help me do what I want to do or not.
I'm very inexperienced in this area so I don't even know if my questions are appropriate, but here goes:
Should I even be looking at django packages?
Would looking for a python based auth server be more appropriate?
Where should I start to solve this problem?
No, you don't need a separate package. Just use Django's built-in multi-database handling. Check out: https://docs.djangoproject.com/en/dev/topics/db/multi-db/.
Essentially, you designate one of your databases as the one that's going to store the user data and make sure that database is added to each of your other projects. Then set up a router that checks for app_label=='auth' and route to the "user" database for those instances. There's an example in the docs.
I'm trying to make a website that allows you to setup a photo gallery with a custom domain name.
Users of the site don't know how to register or configure domain names, so this has to be done for them.
User enters desired domain name in a box (we check if it's available) and click 'register' button and our website registers the domain name for them and sets up the website automatically (when user goes to that domain name, the photo gallery just works, no technical skills needed).
Enom has an API for resellers which could let you automatically register a domain on behalf of a user. (I have no affiliation with eNom, nor have I used eNom's products).
Implementation of *.weebly.com
Typically this form of dynamic sub-domaining will use a Wildcard DNS record. This type of record maps a wildcard pattern like *.example.com to one or more servers.
Let's say you have a blogging site and want to let users choose domain names dynamically. You put up a webpage on www.example.com with a form to let user's select names. So a user signs up and chooses bar.example.com.
Suppose your DNS server has the following mappings:
foo.example.com > 1.2.3.1
*.example.com > 1.2.3.2
Any request for foo.example.com will route to 1.2.3.1, but any other name, such as bar.example.com, will be served by 1.2.3.2. So when the user is redirected to http://bar.example.com the browser will hit 1.2.3.2. Note that since no DNS changes needed, there is no propagation delay: the redirect will work instantly.
The software running on 1.2.3.2 would then examine the Host header in the request, parse the fqdn and strip off .example.com, and resolve bar against a database. If a record exists, it will serve up the appropriate response for bar.
You'd also want to keep a list of reserved names or patterns you plan to use in the future, like www\d*, mail\d*, ns\d*, so that when a user tries to register the site www07 your blacklist will reject it.
Mapping any domain to bar.example.com
Once the bar.example.com site exists, the user may want to map a custom domain name like www.widgetsimakeinmyhome.com to their site. The registration and setup for this is mostly manual, and sites like EasyDNS make it pretty simple. Some registrars may have APIs to make part of this easier for you. These should typically be RESTful or at least HTTP-based APIs, so you can choose which client library you like to use (e.g. urllib2).
To create the mapping, your database would have a table mapping primary sites like bar to one or more domain aliases. A person would sign-in and map www.widgetsimakeinmyhome.com to bar.
Now your software needs to check the Host header against both the primary site table and the alias table to resolve to the correct site.
There is no general API for this. You have to check back with your own domain registration organization. This is specific to the related domain provider.
I would recommend http://www.zerigo.com/managed-dns ... a managed DNS api solution. I noticed this service existed when a large website provided mentioned something about them. I'm thinking about using them in my next project (similar setup to what you want) and using eNom for domain registration.
Usually you register a domain via a registrar. These companies often provide proprietary APIs which you can use to do this in an automated way. (Some registries also allow registration without using a third-party registrar, for example DENIC)
The registrar then orders the domain at a registry specific to the top level domain. For the communication between registrar and registry the Extensible Provisioning Protocol was created.
Some registrars also implement EPP as an API for their customers so in theory you could use this protocol and switch to another registrar without having to use a new API. I have not done this yet so maybe you have to make adjustments when you actually switch registrars.