I'm planning to do an Desktop application using Python, to learn some Desktop concepts. I'm going to use GTK or Qt, I still haven't decided which one.
Fact is: I would like to create an application with the possibility to be called from command line, AND using a GUI. So it would be useful for cmd fans, and GUI users as well.
It would be interesting to create a web interface too in the future, so it could be run in a server somewhere using an html interface created with a template language.
I'm thinking about two approaches:
- Creating a "model" (core module, where all the functionality resides) with a simple interface which is called from a desktop/web implementation;
- Creating a "model" with an html interface, and embeb a browser component so I could reuse all the code in both desktop/web scenarios.
My question is: which exactly concepts are involved in this project? What advantages/disadvantages each approach has? Are they possible?
By naming "interface", I'm planning to just do some interfaces.py files with def calls. Is this a bad approach?
I would like to know some book recommendations, or resources to both options - or source code from projects which share the same GUI/cmd/web goals I'm after.
Thanks in advance!
What about a link to the source?
Having a CLI command and a GUI front-end is really common on unix platforms... The TransmissionBT bit torrent client is a good example of what you plan to do.
Decoupling the presentation layer from application logic makes it possible!.
You can divide your application into layers, a layer is a reusable portion of code that performs a specific function.
For example, you can divide the application into two or more layers, one layer with the presentation of the application and the other with the model. This allows reuse of the entire model of the application with different implementations of the presentation layer.
The presentation layer contains the components that implement and display the user interface and manage user interaction. This layer includes controls for user input and display, in addition to components that organize user interaction. Can have multiple implementations of the presentation layer technologies such as PyQt4, PyGtk, Html, console, etc.
Why Separating Model Is Useful?
You may wonder why it is important to move as much logic outside the presentation layer and into the model layer. The biggest reason is reuse: logic placed in a model increases the reusability of an application. As applications grow, applications often grow into other realms. Applications may start out as a web application, but some of the functionality may later be moved to a smart client application. Portions of an application may be split between a web site and a web or windows service that runs on a server. In addition, keeping logic helps aid in developing a good design (sometimes code can get sloppier in the UI).
However, there are some caveats to this: it takes a little longer to develop applications when most of the logic resides in the business layer. The reason is this often involves creating several sets of objects (data layer and access code, plus business objects) rather than embedding it in the application. The extra time that it takes to do this can be a turnoff for some managers and project leads, especially because it often requires you to be knowledgeable about object-oriented programming, more than most people are comfortable with.
You can search about N-Layered architectural style on the Internet.
This is a sample application that implements several types of user interfaces, but based on. NET framework, for python is similar.
http://microsoftnlayerapp.codeplex.com/
I am working on a big project based on PyQt4 presentation framework. one of the styles of architecture applied is N-Layers. If you want a simple example based on PyQt4, send me a email.
Related
I've found an example: https://medium.com/velotio-perspectives/a-comprehensive-tutorial-to-implementing-opentracing-with-jaeger-a01752e1a8ce
I have a pretty large codebase and I really don't want to modify every function by adding a line like ' with tracer.start_span('booking') as span:'. Is there any way to do it?
Thanks in advance.
Jaeger is a distributed tracer, inspired by Google's Dapper paper, and so it is mainly used for tracing communication between different processes in a microservices / distributed system architecture, not so much for portions of code inside an application.
The way Jaeger is introduced into most applications is to integrate it into the part of the application that is receiving requests from the network. For example, if your Python application is receiving HTTP requests using Django or Flask, or other types of requests (e.g. gRPC) using some other framework, there will probably be a project somewhere on the internet that lets you hook Jaeger into your framework with a couple of lines of code. For the most popular frameworks, the Jaeger docs point to opentracing-contrib as a good source for these "client libraries".
While making extra tracing calls inside an application is not unheard of or discouraged with d.tracers, it's not something that tends to happen a lot, because d.tracers are typically used in microservices environments where the interactions between components are more important than what's happening inside the components.
If you do want to create tracing records inside an application, then it would be very unusual to do tracing of every single function. Instead, tracing inside an application would typically be done at the boundary of components in a modular monolith, i.e. when one component calls into another component.
Lastly, if what you really want is performance analysis of your single Python application at the level of each function, and you don't care about it's interaction with other applications in your system (maybe you only have the one?), then Jaeger is probably not the right tool. In that case, you would probably want to look for an Application Performance Monitoring or APM tool that works with Python and suits your needs.
How does one properly structure a larger django website such as to retain testability and maintainability?
In the best django spirit (I hope) we started out by not caring too much about decoupling between different parts of our website. We did separate it into different apps, but those depend rather directly upon each other, through common use of model classes and direct method calls.
This is getting quite entangled. For example, one of our actions/services looks like this:
def do_apply_for_flat(user, flat, bid_amount):
assert can_apply(user, flat)
application = Application.objects.create(
user=user, flat=flat, amount=bid_amount,
status=Application.STATUS_ACTIVE)
events.logger.application_added(application)
mails.send_applicant_application_added(application)
mails.send_lessor_application_received(application)
return application
The function does not only perform the actual business process, no, it also handles event logging and sending mails to the involved users. I don't think there's something inherently wrong with this approach. Yet, it's getting more and more difficult to properly reason about the code and even test the application, as it's getting harder to separate parts intellectually and programmatically.
So, my question is, how do the big boys structure their applications such that:
Different parts of the application can be tested in isolation
Testing stays fast by only enabling parts that you really need for a specific test
Code coupling is reduced
My take on the problem would be to introduce a centralized signal hub (just a bunch of django signals in a single python file) which the single django apps may publish or subscribe to. The above example function would publish an application_added event, which the mails and events apps would listen to. Then, for efficient testing, I would disconnect the parts I don't need. This also increases decoupling considerably, as services don't need to know about sending mails at all.
But, I'm unsure, and thus very interested in what's the accepted practice for these kind of problems.
For testing, you should mock your dependencies. The logging and mailing component, for example, should be mocked during unit testing of the views. I would usually use python-mock, this allows your views to be tested independently of the logging and mailing component, and vice versa. Just assert that your views are calling the right service calls and mock the return value/side effect of the service call.
You should also avoid touching the database when doing tests. Instead try to use as much in memory objects as possible, instead of Application.objects.create(), defer the save() to the caller, so that you can test the services without having to actually have the Application in the database. Alternatively, patch out the save() method, so it won't actually save, but that's much more tedious.
Transfer some parts of your app to different microservices. This will make some parts of your app focused on doing one or two things right (e.g. event logging, emails). Code coupling is also reduced and different parts of the site can be tested in isolation as well.
The microservice architecture style involves developing a single application as a collection of smaller services that communicates usually via an API.
You might need to use a smaller framework like Flask.
Resources:
For more information on microservices click here:
http://martinfowler.com/articles/microservices.html
http://aurelavramescu.blogspot.com/2014/06/user-microservice-python-way.html
First, try to brake down your big task into smaller classes. Connect them with usual method calls or Django signals.
If you feel that the sub-tasks are independent enough, you can implement them as several Django applications in the same project. See the Django tutorial, which describes relation between applications and projects.
I'm going to be writing a fairly sophisticated command line app in python. I'd like to leverage something other than just pure python, maybe a framework or something that makes the services and code management within the app easier. I guess in my mind, I'm thinking MVC, as the app will have several different commands (controllers) which call different sources for data (JSON requests, REST requests, etc., e.g. the "Models" in MVC), and then display results in different formats (the View).
I think MVC works well for this, but I'm not really doing a web app. I want something that doesn't necessarily require a web server, but has the advantages of a framework to force some coding standards.
Does anyone have any tips or suggestions? I know I could build something from scratch with Python, but I'm just curious if there's something else out there I could utilize.
Thanks,
Dustin
This is a bit late, however posting for anyone else who stumbles across this:
Cement is an Advanced CLI Application Framework for Python. Getting started is easy, and it is extremely flexible for customizing almost every piece of it from logging to config file parsing. Cement2 (code name portland) is currently in beta, but is very close to a stable release:
http://cement.readthedocs.org/en/portland/
Additionally, if you are creating a REST command line client, also checkout dRest:
http://drest.readthedocs.org/en/latest/
It too is very easy to get started with, and is also extremely flexible for customization from the request handler, to how serialization happens on both the sending and receiving ends.
I'd be happy to answer any questions about either.
To be fair to the pattern, MVC is not bound to web applications. I think because of the web-aware trend of the last couple of years this relation between MVC and web apps could have grown. Put differently, a web app can use MVC, but using MVC doesn't necessarily mean that you have a web app.
If you want to use a framework, you could try to use the one most close to your intended controller. I'm not aware of an MVC frameworks that have a command line as the interface, but some platform independent GUI frameworks that use it are for example GTK+ or QT: both have python bindings.
From a personal point of view, I've used Django for this purpose before. Although the technical purity can be a point of discussion, when selecting a framework no one forces you to use all of the framework's components. Django has a nice ORM which I've liked so much that I made it the backend for a SSH operated interface. It might be overkill, but for me had the advantage that I could reuse my knowledge about the system instead of learning a new, once-to-be-used framework.
In conclusion, it all boils down to discipline. Even the best framework cannot prevent you from violating coding standards and cutting corners...
PS if you're on Linux, you might consider using python's curses module for your command line frontend.
Could I assume that every powerful application would provide a command line/script input?
Even there are many many fancy widgets in current software, but I still think command line input mode in UI is still necessary nowadays, since command line/script input is more straight forward and neat. If application could provide more domain specific script language, that would be more powerful.
Is there some book provide some theory on this? Effective UI?
You ask about books related to the theory of this. The theory is one of separating presentation logic from business logic, or separation of concerns. This goes by many names such as model/view/controller, model/view/presenter, and many others, and there are plenty of books on the subject.
If you design an application this way, the presentation layer (ie: user interface) is a separate entity that can be replaced with another. Thus, you could have a graphical user interface as well as a textual one. Arguably, in a perfect world all apps would work this way, with a desktop UI, a web UI, a command line UI, and so on.
This all comes at a great cost, however. It is difficult to design applications in this way and, because of the loose coupling between the application and the UI there may be performance penalties. To further add to the difficulty, it is inherently difficult to provide a rich command line interface to a complex application. How would you go about creating command line input to Adobe photoshop or Microsoft Excel, for example?
So while it's possible in a theoretical sense, from a practical sense it becomes more difficult as the complexity of the UI goes up. There are many applications that are able to accomplish this, however. For example, many version control systems such as BitKeeper, AccuRev and others have both command line and graphical interfaces.
So, yes, it's possible that most applications could implement both a graphical UI and a command line UI, and it's true that a few of them do, it's not reasonable to expect that all applications will or even can.
I'm working on a poker analysis tool with the following use case:
User create Strategy class with one method: input GameState, output PokerAction
User runs Analysis script, which launches a PokerGame between various Strategy subclasses (i.e. various strategies)
PokerGame generates random deck
PokerGame sends GameState to Strategy
Strategy sends PokerAction to PokerGame
PokerGame updates GameState
When the game is done (managed by PokerGame), send GameResult to Analysis script
User reviews output of Analysis script
There's a third-party library that performs all of the PokerGame functionality. It doesn't match at all with my own modeling of the domain in some areas (e.g. card values, etc.) but performs much of the "hard-to-code" functionality that I need (i.e. the non-trivial steps 4 - 7).
General design question
When faced with a library like this (eliminates a lot of hard coding, but might constrain future design choices in related projects), do you tend to mold the rest of your project to the library? Do you refactor the key library to conform to your domain model? Or is it something else?
Thanks,
Mike
If I really felt my domain model better suited me going forward, I would try to create an abstraction layer to map between the 3rd party library and my own model. This would allow me to take advantage of the library now while providing me with the flexibility to replace it in the future with another 3rd party library or one I created.
Take a look a this list of design patterns, especially the Adapter Pattern.
I would not couple my project tightly to the library, but instead try to abstract functionality and couple both using one or more objects in between. The mediator and/or facade pattern come to my mind here.