 I'm Magdalena. I'm a Django Becken developer from Berlin. I work for the digital agency MOKU. A challenge I meet in my everyday work is working with many projects and frequently switching between them. This is why I am interested in project structure and configuration. In my talk, I will talk about some tools and techniques, how to approach this challenge. I implemented a sample project, Draw DevOps Against Humanity. It is based on a card game, DevOps Against Humanity. In this game, you need to draw cards and create fun sentences about development and operations. All sentences, phrases and words as well as card templates are available in open source repository, in Brigitte-Kromhauer repository under the Creative Common license. Now, let's have a look at the Draw DevOps Against Humanity project. The project structure. I want to find things in my project easily. I don't want to dig into each folder and file to find the right place to add a new function or a new test. What can we do about it? We can use a standard structure. In case of Draw DevOps Against Humanity, we have a data folder for data, a draw folder for the main project code and a test folder for tests. You may already know this structure because this structure is described by the Python packaging user guide and it is also available in sample project repository. This repository contains along with this nice folder scaffold also a bunch of files. These are setuppy, some metadata about project and configuration files. Some of these files are empty, others are already prefilled for us. So, for example, setuppy already imports setup tools and has setup function with default arguments. Moreover, each of the default arguments has extensive documentation above, so it is easy to exchange it for the real specific for the project argument. In this talk, I will concentrate on three files that are already provided by sample project and we will add on the way three additional files to this collection. But first, before we jump into the configuration, let's have a look what Draw DevOps Against Humanity does. Let's draw us a sentence. We're starting from backup space due to a cold cup of coffee. I imagine it could have happened. And now, dot git ignore. I want to have in my repository only the files that belong there. I don't want to include an auto-generated files as they can lead to bugs. What can we do about it? We can from the project start include git ignore. Some templates for git ignore are provided by github in their git ignore repository. They have their templates for over 100 languages. These templates are very elegantly structured. They are ignored file or structure are classified based on their origin, so it is quite transparent and easy to extend. You can also bar in mind especially for open source project that also code editors and different operating platforms systems also produce some auto-generated files and also for these git ignore repository provides templates in their global folder. And now, another break. So what does DevOps Against Humanity says? It says 90% of everything is a jar full of spaghetti. I don't know, but I like spaghetti. Setup CFG. Setup config is a file where we can configure our setup. We can include their information metadata about the project and also serve as interface for configuring different command line tools. For example, we can configure here PyTest, Nose, Coverage, Flakes8, Isort or Sphinx. Each of these tools could be configured in each own separate RC or any file but we can choose to have one common interface. In case of DevOps Against Humanity, we will use setup config to configure our tests. So first, when we run our tests without any configuration, PyTest will run our eight tests and it will tell us that they pass but we want to have something more verbose. So we add some configuration in setup config. In first part, we say which tool we want to configure it and with adopts line, we say what should happen when we run PyTest command. So we want more verbosity, we want to allow the bugger, we want to have short traceback and we want to always include PEP8, Flakes and Isort plugins. Additionally, in these files, we can also configure our plugins for tests and we can add some style configuration. For example, here we say that we want to have longer lines with 96 characters and that we want to ignore some PEP errors. So now, when we run our tests, there are indeed more verbose. A part of our eight tests, PyTest run for each of our code file also a test for PEP8, Flakes and Isort, checking whether our style is correct. In case of some of the style checking, test remembers what was the result and if the file didn't change since the last run, the test is skipped. This is why some of the tests here are yellow and are marked as skipped. So now, as we configured our tests, we deserve another treat and we can give ourselves a sentence. There was no good solution for CEOs with root access, so we built our own. Another thing, editor config. I want to have a consistent style guide in the project. We already said that we can enforce our style with some tests configuration, what we can do additionally, we can use editor config. Editor config enables to create and maintain style guides for projects. We have a configuration file.editorconfig and there we can put how we want our different files to look like. Editor config provides also a large set of plugins for different editors so they can read the configuration and actually automatically configure our format, our files in the desire with the desire style guide. Surprise, surprise. The next sentence is, I made a new editor better than Veeam and Emacs. Oh, is it possible? It's called Twitter. The next thing I would like to have is I would like my project to run under different Python versions. A tool that comes in handy here is pyenv. Pyenv is a tool that enables installing and managing different Python versions on your computer. You can configure it by setting environmental variables or also explicitly saying in .python version file which versions you need. In this case, Python 3.5, 3.4, 2.7, with the first being the default one. And now, Hacker news. It's how I resolve all my merge conflicts. I don't know about you, I don't. Apart on running our tests, our project in different environments, we may also want to test it under different environments and with different Python versions. And a tool that can help us here is Tox. Tox is also an example, one of the examples of tools that cannot be configured in setup config. It requires separate configuration file, Tox.ini. And here we see an easy sample configuration. In the first two lines, it says which environments we want to use, our free Python versions. And in the second part, it says what should happen in each of these environments. So we want to, in each of the environments, we want to install our dependencies which are defined in setup.py. And then in each of these environments, we want to run PyTest with coverage. So we run Tox. And we expect that this beautiful picture of passing tests will appear on our screen. But unfortunately, it's not what happens. We get an error, Python 3 passes, but Python 2 complains about some type error. And indeed, we dig in our code, we check what's happening, and we see that one of our tests is creating in-memory file, in-memory CSV file, and that's a problem. In Python 3, CSV requires file open under the string mode, but in Python 2, it requires file open under byte mode. So we quickly fix this issue and run our Tox again. And now all the tests are passing and Tox is smiling at us. Of course, it doesn't mean that our tests, that our project is 100 correct, as we already heard in quite a few speeches during this conference. But at least we know that the things that we tested, that the way they work consistently under all this free environment. And yay, Tox just saved us from pushing buggy code to the repository. So after this heavy debugging, you agree that we deserve a treat and we get another sentence. Git, you are in a detached Indian Ocean state. Now it's time for our final file, Makefiles. Makefiles are typically used in C, with C programs, but Makefiles can also make life of Python programmers easier. And they provide a way to automatize some common tasks. So if I don't want to run a long command or long set of commands, I can just write Makefile. Here in this example, we have Make command for running tests, for running coverage, and for development installation of the project. But you can add anything you imagine, you can clear your pick files, you can clear your build files, you can run your server. It also provides documentation for your project, about most typical things you can do with that. So that's the Makefile. And the final, your DevOps against humanity sentence is, to secure our next round of founding management says we need kill minus nine, tough one. Now to sum up, if you are in a situation that you are dealing with many projects and you need to switch between them, there are some things that can come in handy. You can use a standard structure for your project. You can keep your repository clean and take care that unnecessary files won't be included in the repository. You can take care of the style so the code gets more readable. You can enforce good style with test configuration, which we did in setup config, and you can also provide editor config for that. You can use different environments and use pyenv for that, which is configured in .pyton version. And you can use docs for running tests under different Python versions. Finally, you can automate common tasks for the project in the make file. Examples of configuration that I just show is provided in my repository, Lena Rotter draw DevOps against humanity. And if you are in such position and when you are happy with the structure of the project that you have and with the configuration you have, then you can... A good next point where you can look at is cookie cutter. Cookie cutter enables creation of templates then you can then duplicate into projects. And that's all from my site. I would like to thank the developers I had pleasure to work with and some others that inspired me on my way. Thank you very much for coming. Thank you, Magdalena. If you have any questions, please raise your hand. Hi, thanks for the talk. Do you know website gitignore.io? It's a perfect reference instead of downloading the gitignore files. Just write what are you using in the project like Python, Django, PyCharm, everything and it will automatically generate the gitignore file for you. I think it might be worth mentioning that. Nice. So once again, I didn't know that. What's the name of the tool? gitignore.io. It's a website. Gitignore.io. How does talks find all the Python versions? Talks? Could you repeat what's the question about the talks? How does it find the Python versions that are installed? It works together with PyEnv. So there is talks.pyenv.plugin and this is how it finds the different versions. So you can use pyenv to install different versions of Python and then talks will be able to find them. Any other questions? Hello. Could you go back to the talks, any you have on the slides? This one? So it's here. So I think it's not good if you use dApps equals .tests because what it does is it actually installs things before installing the source package of your package but you should actually use dApps equals .tests. So it's supported in talks 2.4 onwards. So I'm all using extras and tests is name of my extras and here I am installing the requirements for extras that is called tests. Yeah, sure, sure. But talks since version 2.4 has a special setting called extras just for this. So update your talk to use that. Thank you. Hi, thank you for this very informative talk that is quite useful for setup in project. I wanted to ask if there is a way to condense informations in last file or if we should provide for example all the Python version in more than one source for example in talks from dApps.cfg in setup.py or if there is a way to have just one file for a global reference for everything and import those informations from talks from setup and so on. So there are different opinions among developers whether there should be a way to do that or whether it's more pretty depends a bit on the people who provide a tool which ways of configuring the tool they provide. So many tools enable this setup config configuration so you can configure it provide the configuration of different tools in this one file but there are some like talks that doesn't support it so then you need to I wanted to add one thing to your question so it's not that possible to have one file because these are Python files YAML files and sometimes Tomo files so there are some attempts to prepare something called pip file which will be in the Tomo language but I think Python Packaging Authorities are working on that so I don't think we will see that so soon Do we have any more questions? It doesn't look so Thank you Thank you so much Please don't forget to rate this talk in the app