DjangoCon 2014: Lightning Talks
This is a modal window.
The media could not be loaded, either because the server or network failed or because the format is not supported.
Formal Metadata
Title |
| |
Title of Series | ||
Part Number | 42 | |
Number of Parts | 44 | |
Author | ||
Contributors | ||
License | CC Attribution - ShareAlike 4.0 International: You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal purpose as long as the work is attributed to the author in the manner specified by the author or licensor and the work or content is shared also in adapted form only under the conditions of this | |
Identifiers | 10.5446/32841 (DOI) | |
Publisher | ||
Release Date | ||
Language |
Content Metadata
Subject Area | ||
Genre | ||
Abstract |
|
DjangoCon US 201442 / 44
2
3
7
8
10
11
13
14
18
26
29
32
38
39
42
43
00:00
Prisoner's dilemmaNetwork topologyCuboidWeb-DesignerEndliche ModelltheorieForm (programming)Projective planeOpen sourceFood energyGenderClient (computing)Text editorDependent and independent variablesDrop (liquid)Drag (physics)Data structureContent (media)XMLUMLComputer animation
00:52
Computer programmingEndliche ModelltheorieType theoryForm (programming)Field (computer science)Medical imagingWebsiteMultiplication signClient (computing)Different (Kate Ryan album)Content (media)Validity (statistics)outputData miningStudent's t-testGame controllerDrop (liquid)Computer animation
02:20
Data modelNetwork topologyKey (cryptography)AdditionOnline helpType theoryText editorDrag (physics)Reading (process)Drop (liquid)Different (Kate Ryan album)Content (media)VideoconferencingWrapper (data mining)DebuggerGUI widgetForm (programming)Endliche ModelltheorieSocial classField (computer science)Goodness of fitMedical imagingNP-hardProgrammer (hardware)Game controlleroutputComputer filePhysical systemAxiom of choiceWebsiteComputer programmingComputer animation
04:36
Link (knot theory)Ideal (ethics)Context awarenessGraphical user interfacePattern languageData managementBitSoftware developerGUI widgetWeb 2.0Physical systemTorusBoundary value problemBinary codeTotal S.A.Mobile WebComputing platformEvent horizonCodeStability theoryGodMereologyUser interfaceDependent and independent variablesWeb browserGroup actionoutputFrustrationMultiplication signCollisionOpen setIntegrated development environmentDemo (music)BijectionProjective planeWindowLibrary (computing)Template (C++)Ferry CorstenSource codeCalculationGenderProcess (computing)CuboidRight angleCartesian coordinate systemVideo gameQuicksortWritingWorkstation <Musikinstrument>WeightSoftware testingTouch typingSinc functionRandomizationInterpreter (computing)DemoscenePoint (geometry)Keyboard shortcutInstallation artLine (geometry)Term (mathematics)Enterprise architectureSeries (mathematics)Android (robot)State of matterTwitterHydraulic jumpSuite (music)Graph (mathematics)Mobile appOpen sourceVirtual realityThread (computing)Loop (music)Position operatorType theoryGoodness of fitComputer configurationCompilerMoment (mathematics)View (database)Computer animationLecture/Conference
09:46
Functional (mathematics)Image resolutionBitNumberData storage deviceInformation securityField (computer science)CASE <Informatik>EllipsoidDatabaseMultiplication signBlock (periodic table)Structural loadEndliche ModelltheorieMessage passingLibrary (computing)String (computer science)MereologyQuicksortInstance (computer science)File formatPattern languageCryptographyLink (knot theory)InformationUtility softwarePosition operatorGraph (mathematics)Software bugExtension (kinesiology)Key (cryptography)Operator (mathematics)SoftwareSet (mathematics)Query languageEncryptionTransmissionskoeffizientData conversionPersonal identification number (Denmark)Computer fileImplementationState of matterRootOrder (biology)Software developerLevel (video gaming)Category of beingMathematicsHierarchyOpen setAreaProcess (computing)ResultantGraphics tabletSelectivity (electronic)System callSubject indexingDeclarative programmingFiber (mathematics)Object-relational mappingComputer animationLecture/Conference
16:40
Execution unitTask (computing)EstimatorSet (mathematics)Parameter (computer programming)Level (video gaming)Message passingLatent heatAverageView (database)Module (mathematics)Multiplication signCASE <Informatik>Endliche ModelltheorieInternetworkingElectronic mailing listRight angleBranch (computer science)Run time (program lifecycle phase)Client (computing)GenderIntegrated development environmentTemplate (C++)NumberTerm (mathematics)WordComputer fileData managementParticle systemData structureCoefficient of determinationSoftware developerProduct (business)Row (database)Gastropod shellPresentation of a groupReflection (mathematics)ArmKey (cryptography)Information managementConfiguration managementVideo gameMereology1 (number)Line (geometry)Metropolitan area networkArithmetic meanVolume (thermodynamics)Form (programming)PlanningAreaQuicksortPhysical systemCodeGroup actionMobile appVariable (mathematics)Projective planeSurfaceGoodness of fitAuthorizationRepository (publishing)CountingMathematical analysisBuildingVirtualizationCoprocessorDirectory serviceBootstrap aggregatingVideoconferencingVarianceCore dumpDebuggerConfiguration spaceServer (computing)Computer animation
23:33
Online chatServer (computing)StatisticsSystem administratorPublic key certificateFunctional (mathematics)Staff (military)System callCASE <Informatik>Game theoryWrapper (data mining)Software developerMultiplication signMusical ensembleBitProcess (computing)Goodness of fitSoftwareSoftware testing2 (number)Instant MessagingThread (computing)TelecommunicationEmailPattern languageProduct (business)Coma BerenicesSoftware frameworkNetwork socketRight angleInheritance (object-oriented programming)Type theoryPoisson-KlammerTable (information)Web pageMereologyService (economics)Cycle (graph theory)Mobile appInstallation artEvent-driven programmingReal-time operating systemDifferent (Kate Ryan album)Web 2.0Configuration spaceObject-relational mappingComputer animation
28:59
SpacetimeGraph (mathematics)GenderWebsiteWeb pageSystem callProcess (computing)Single-precision floating-point formatProduct (business)String (computer science)Validity (statistics)Data structureCellular automatonFlow separationMultiplication signMereologyCodeMobile appParallel portSoftware frameworkContent (media)Limit (category theory)Game controllerView (database)Direction (geometry)ResultantProjective planeMetropolitan area networkInteractive televisionNumberDirectory serviceRepresentational state transferComputing platformPower (physics)Computer fileSet (mathematics)Software developerSlide ruleDomain nameConfiguration spaceBasis <Mathematik>Template (C++)DiagramEndliche ModelltheorieQuicksortComa BerenicesStaff (military)Combinational logicImplementationCore dumpMixed realityShared memoryUtility softwareoutputPiAuthenticationModule (mathematics)Computer animation
34:16
Human migrationGenderView (database)Set (mathematics)Projective planeMultiplication signLogicNormal (geometry)QuicksortSoftware developerFormal grammarEndliche ModelltheorieConfiguration spaceLibrary (computing)State of matterPlug-in (computing)TypprüfungImplementationPresentation of a groupOpen sourceFront and back endsBit rateRight angleScripting languageDivisorProduct (business)MedianOcean currentNumberCore dumpPhase transitionMathematicsFunctional (mathematics)Pattern languageVariety (linguistics)InjektivitätObject (grammar)Error messageSocial classComputing platformScatteringField (computer science)Division (mathematics)Computer fileMachine visionPlanningFigurate numberEmailFormal languageCASE <Informatik>Point (geometry)Type theoryQuadrilateralTask (computing)Default (computer science)MereologyLogical constantMobile WebAddress space2 (number)Coma BerenicesForm factor (electronics)AuthorizationAdditionComputer animation
39:38
Different (Kate Ryan album)Representation (politics)ArmComputing platformField (computer science)Set (mathematics)Attribute grammarForm (programming)Library (computing)Incidence algebraWordCartesian coordinate systemValidity (statistics)Client (computing)Form factor (electronics)CuboidMetropolitan area networkFront and back endsProcess (computing)Rule of inferenceInstance (computer science)Software frameworkSoftware testingBuildingDivisorKey (cryptography)Multiplication signEuler anglesNumeral (linguistics)Order (biology)Natural numberType theoryNumberDynamical systemMobile appVolumenvisualisierungStructural loadGeneric programmingSelectivity (electronic)outputWeb 2.0View (database)Demo (music)Server (computing)Endliche ModelltheorieSystem callRight angleAndroid (robot)BitCodeComputer animation
44:59
Open sourceGene clusterEvent horizonRing (mathematics)Lattice (group)QuicksortNumberClosed setWordSampling (statistics)HypermediaOpen setOffice suiteComputer animation
45:50
Goodness of fitInformationBitTouchscreenRadical (chemistry)Computer animationLecture/Conference
46:51
Configuration spaceServer (computing)TouchscreenBranch (computer science)PixelComputer fileMereologyRootTesselationDirectory serviceProduct (business)Electronic mailing listMathematicsDifferent (Kate Ryan album)WindowException handlingPower (physics)Gastropod shellTerm (mathematics)Commensurability (mathematics)Flow separationBinary fileCellular automatonProjective planeEndliche ModelltheorieComputer animation
49:45
Revision controlMedical imagingDependent and independent variablesSoftware development kitHome pagePopulation densityPixelTraffic reportingSoftware frameworkRule of inferenceWeb browserAdaptive behaviorMultiplication signFront and back endsWebsiteRun time (program lifecycle phase)Functional (mathematics)CASE <Informatik>Event horizonDebuggerCausalitySource codeImage resolutionObject (grammar)Computing platformSoftwareRight angleProfil (magazine)Scripting languageSemantics (computer science)MereologyDomain nameService (economics)Markup languageHTTP cookieCombinational logicWeb pageMathematical optimizationProjective planeAttribute grammarPivot elementGodServer (computing)WordSystem callNamespaceSpacetimeIntegrated development environmentQuantum entanglementWave packetStructural loadTerm (mathematics)Data compressionProcess (computing)Figurate numberQuicksortTowerGenderComputer animation
55:03
Multiplication signElement (mathematics)Real numberProcess (computing)CollaborationismProjective planeAxiom of choiceBitRepository (publishing)Level (video gaming)Stress (mechanics)SoftwareVapor barrierLine (geometry)Software frameworkOnline helpArithmetic meanVideo gameConfidence intervalDrop (liquid)Formal languageComputing platformComputer clusterKey (cryptography)Goodness of fitCodeWeb 2.0Computer animation
59:36
Computer animationDiagram
Transcript: English(auto-generated)
00:21
Hi, my name is Rocky Mesa. I'm Gavin wall, and we're here to talk to you about form builder Or hey look what you can do with WIGI and the tree model We work at fusion box fusion box is a Django web development agency in Denver and fusion box one of our open source projects is WIGI WIGI is a
00:41
Content editor that we made in response to some of the problems that our clients had that we've been seeing with our clients It's a drag-and-drop editor for tree structures So a problem that we've encountered frequently is a client is asking us for the ability to dynamically create a form on their website
01:01
without any programming So they want to specify what fields they want They want to specify validation for those fields and they want to control what happens when the form submits so We've actually built a bunch of these form builders for clients before and every time we do it We would run into some problems. So like if you wanted to have different models for different types of fields
01:25
It doesn't really work really well with just what Django gives you if you want to have like an input in a drop-down Those have different fields, but you have to put all the data in one model and then and it's kind of gross ordering you can do that with something like the in-lines and Django admin sortable, but
01:45
It limits you to just having one model and then on top of that for example one time we had a client that had a Field that referenced an image and they needed the image to be inside of the form so they could refer to the image So it's it's kind of hard to have
02:02
Non form content inside your form when you can only deal with one model and on top of that when you're done when you've made it You can't really package it up and put it on PyPI because it's not extensible if anybody wants to add a field type They have to edit your original field model But that was before WIGI
02:24
WIGI's data model is a heterogeneous tree. What that means is it's a tree where the nodes can be different types That's implemented as a tree beard tree of nodes each with a generic foreign key to their content In addition to the data model, WIGI also provides the UI for manipulating that tree
02:43
We built a drag-and-drop editor to edit the tree data So how does WIGI help with this? Let's look back Here's a here's the reasons why it was kind of hard and a good form builder would overcome these Ordering forms mixing different types of fields having non form content and being sensible
03:04
So if we look at ordering forms Django tree beard gives us this and WIGI gives us an editor for it So it's already done. We don't have to think about it The generic foreign key allows us to reference any type of content So we're now able to use a different model for each of our fields
03:23
Interspersing non-form content just like Gavin said we can use any model so we can add Images and videos and Google Maps and we just do it Since the generic foreign key is able to reference any model. Sometimes you want to limit that So WIGI provides a compatibility system that allows you to specify which tree relationships are possible
03:45
So if you want to add a new field type You can write a model and then specify that it goes in a form and now WIGI is able to add that field to a form So we went ahead and built a form builder with WIGI and you can see it right there
04:01
you've got different types of Form fields like choice field form input file upload and you can just drag them and drop them interspersed non-form content It's got a form wrapper widget and that form wrapper widget It's got a cool method called get form which returns a Django form class
04:20
So you don't have you everybody's familiar with Django form classes You can just use that but the user built that form instead of the programmer And here's what it looks like on the front end so the user has complete control over this form Thanks, guys. We're out at we got a booth over there and we've got these links
04:43
They should look at WIGI, WID.G. There's a demo and it's on github. It's open source It's on PyPI. Thanks guys. Come talk to us if you have any questions At DjangoCon US last year. I launched the B-ware project. B-ware is an umbrella project
05:05
I've been running in my what I laughing referred to as my spare time in which I'm hoping to collect a bunch of useful graphical development tools for Testing coverage debugging the sort of things that we do in a day-to-day life as as Python developers The cornerstone of B-ware at the moment is cricket a graphical tool for running your test suites including Django test suites and enable you to
05:24
navigate the whole testing process But last year since last year. I've been a little bit quiet. Well, what happened? I'm still passionate about graphical tools and having good tools for development to support development But I've hit a few road bumps most notably I was using TK enter to develop these tools and TK enter doesn't have a web widget or you know a web view widget
05:44
Which is kind of a big thing to be missing in 2014 So I started looking around at my options There are lots of options out there, but none of them really work out of the box really well with Python QT Works nicely, but it's huge and the Python libraries have this really weird limbo state licensing problem
06:01
WX windows is really annoying to install GTKs support for OS X is run X windows Kivy does cross-platform, but it uses themes and I really hate themes So this was very rapidly becoming a yak for me I've got things that I want to do, but I I need a widget toolkit that meets my requirements So about the start of this year. I started shaving that yak and about a month ago. I publicly announced toga
06:26
Toga is a cross-platform 100% system native Python native widget toolkit that's installable using pip install toga. What does all that mean? Well, it's cross-platform. I've got it running on OS X I've got running on on Linux on Ubuntu and I've got some preliminary support for Windows as well
06:44
It's 100% system native. It doesn't use a theme to pretend it's rendering system native widgets It uses system native IP eyes to render system native widgets So a button on OS X is an NS button It looks like behaves like acts like an actual NS button on Ubuntu It's a GTK dot button and these are accessed either using the native Python APIs that exist or a C types binding to the system
07:07
Binaries, but because the system binaries are always there. You don't have to compile anything to get them It's also Python native Python first and part of Nathan and Python native because I'm developing it in and for Python It means the API's feel Python native so you can do things like have context context managers
07:23
And for example, if you've got a long-running Graph along running action that is stimulated in response to a button press most widget toolkits coming from a sea heritage Will tell you to spawn a thread or create a callable That's any input into a timer method that you inject into an event loop in toga. You just yield
07:42
Python gives us the ability to yield and a long-running event handler can yield back to the main event loop There's no timers or callback callback threads required It's a pure Python app. So there's no binaries to ship with it Nothing to compile no compiler required with one small caveat on Ubuntu and virtual environments The installation process is pip install toga and off you run
08:03
So how mature is it? Well, it's only had six months of spare time development But here is a simple Fahrenheit to Celsius calculator running under OS X and here is the same user interface running on the same code running under Ubuntu I've done the most work on OS X so the widget support there is at the point where I can mock up the full cricket user interface using toga and
08:24
The original source of my yak. Here's a really dumb web browser written in 35 lines of code It's got a little bit of documentation the code for this example is part of that documentation There's obviously a lot more to go and there's a basic tutorial And one more thing writing a new GUI toolkit is all fine and dandy
08:40
But it really is a bit pointless if it doesn't support all the hot platforms that everyone using today and that includes mobile platforms So I pointed it here is the same Fahrenheit to Celsius calculator running off exactly the same source code running natively on iOS To be completely clear This is a completely native iOS application running using native iOS widgets on an iPhone from Python source
09:02
Using exactly the same Python source of the desktop application used Unfortunately, it doesn't work on Android yet, but I am working on it I'd love to talk to anyone with Python on Android experience about what might be possible There's also a template project out there if you happen to want to develop a Python app and not use toga Or use some other project out there So if you want details or any more anything else about toga go see pibee.org slash toga or jump on Twitter
09:24
I'm also potentially interested in doing a kickstarter to fund some further development on this with the intention of turning it into something you can Actually use for serious professional enterprise development If you or your company think you might be interested in helping to fund that development paying for commercial support Maybe you're otherwise getting involved. Please get in touch. Thanks very much the unenviable position of following Russell
09:52
very charismatic So my name is Dan Watson. I'm going to be talking about a little Library, I wrote for interfacing with PG crypto PG crypto is a Postgres extension that basically lets you encrypt
10:04
Data inside your database using AES or blowfish ciphers so Why would you want to do this? I mean the most common reason is you have some sensitive information that you want to encrypt in your database But still want to be able to search on in your ORM in Django
10:21
I also have a couple functions that might be useful if you need to deal with ASCII armor Which is a open PGP message format or padding functions for dealing with block ciphers The low-level API which is basically a collection of Python functions for dealing with PG crypto You can see if you're using PG crypto the SQL
10:42
you just encrypt data using a key file or a key string and a cipher and that's what you get back and Basically doing the same thing in Python using pi crypto and a couple utility functions in my library You basically get the same data back. So You could also do the same thing with ASCII armor, which is basically a fancy name for again open PGP message format
11:07
You Can take that same encrypted data and call armor on it and you get back this text string where you can actually store Basically the binary data in a text field instead of a byte a or whatever you want to store it in
11:21
So using the PG crypto dot armor function, it's basically the same you get same message back I Guess the real meat of this is doing it in Django You might have a Django model For an employee say you want to store a social security number secure Salary date hired and you don't want these things to be human readable and you don't want
11:44
To say transmit your key over the network when calling into Postgres So here's an example model with some example data and you can see when you get back the model instance and Try to access an encrypted field. It's decrypted kind of transparently
12:06
What's Django 1 7 the custom lookups are awesome. If you haven't played with them. I highly recommend it You can now query Encrypted fields in the database as you would normal fields without having to pull them into Python first So you can filter on social security number or you can do
12:25
Date hired less than and salary is greater than and you get back query sets and you can see the SQL for that actually looks like All the decryption and conversion to ask your armor is done on the database side so you don't need to do Python processing for it
12:43
That's pretty much all I have if you're interested in talking about it find me later here's a couple links for Padding information open PGP and PG crypto. Thanks
13:14
You talk about the root level, root select, and root lingual, so all the assets could place them.
13:23
So all research foundation is like the NSF over here in the US, the National Science Foundation. The mission is to further research and the development of the state of São Paulo. In this case the NSF is from the whole US and top S of São Paulo is the foundation.
13:44
It's only for the state of São Paulo, like the state of Oregon, the state of São Paulo Brazil, in the southeast part of the country. So here we have the set result of a search for scholarships and research grants in your little library.
14:06
The user is searching for Alzheimer's disease and it has more than 200 results of scholarships and research grants. On the left we have the facets and in the facets we have the root level, so each bolt one is a category.
14:26
And inside of this one there is, for instance, in that case, a field of knowledge and we have four items of agronomical science and so on. And each of these have one year actually, so being, for instance, we can have
14:43
on the left the health science and inside of health science we have collective health. Then it's really medicine, nursing and so on. In Portuguese everything is translated, actually we have in Portuguese and everything is translated into English.
15:06
We have the same hierarchy and this is the same idea, the user can select many of them, many of the facets at the same time, which is quite a problem. And what I'm going to show you guys is the main changes you can do to your haystack implementation in order to accomplish this kind of thing.
15:27
So for root level facets you can choose which one you want, on how you can get it, just like I'm showing you guys implemented. But for root level, first we have like a facet A, which is like the top of the category, and inside of that we have B, C and D.
15:46
And for that we have a map, my search app, and the search index is .poi, which is the common fiber for haystack. The main one is the area, which is the multi-value field, and in the schema XML solar
16:04
declaration we are using the descended map, which is like a folder hierarchy, usually in the solar documentation they explain this like this, but we are using it in a different context, which is not a problem.
16:23
So we are using that slash in the area to make the hierarchy, and we have only the field area search for queries, for filtering the user what he has selected. For root select we are using the tag EX for the solution in solar, and they have also in their implementation.
16:51
Probably they don't have this in haystack because this would only work for solar and not for the other ones that the haystack works with.
17:01
And for that we use the EX tag for the clarity facet, and when you are going to narrow it down, you use the tag with the same name, in this case, NYX. And then narrow it down, in this case I have highlighted the search with areas search exactly, or areas
17:24
search exactly, and then you get the facet counts, which would show exactly like the last part of the slide, when you would get the same results out of the other counts or the other variants in that facet.
17:46
And almost meanwhile you took out all these, but using a surface in each field, let them find which one is Portuguese and which one is English.
18:02
For us it's good because it's only English in Portuguese, but if you are from the UN or something like that, good things could be a mess, so if you have a bad idea, just come to me and we can talk more about it.
18:21
I'm Sumit, I work at Tivix, a small Django consulting company based out of San Francisco. Jeff gave a really good talk I think on Tuesday on Ansible, so I just wanted to sort of build on that and share some of my findings and best practices that I've been using. So some background, what's the need? As a consulting company we get projects in, we want to get up and running very fast, as fast as possible anyway.
18:46
The project goes into production after months of development, well the staging environment is out of sync, well someone knows which packages to install, et cetera, et cetera, so that would be nice to not panic. And then sometimes you have a code branch, you just want to set up an entirely separate environment where you
19:01
can run a branch of your code base and show it to the CEO or the client or whoever it is. And I know Heroku supports it really well, but if you're in AWS or Linode or Rackspace, it's somewhat of a pain. So why Ansible? We really like the philosophy behind it, it's agent-less, so if you like Fabric you'll definitely, or you might like it.
19:21
Batteries included, tons of modules, so you don't have to scour GitHub to find the right module you need or may need, et cetera, so they have a certain list of approved ones, you can write your own obviously. Lots of releases, 7,000 followers on GitHub, that's my unscientific way of finding out what's good or not. Chef has 3,000 by comparison, the company behind Ansible has raised $6 million so that it's only going to get better and better over time.
19:44
Technically speaking, why would you want to use it? Configuration management, what packages my server needs, things like those, orchestration and deployment, you could potentially just ignore orchestration and deployment, just use it for configuration management. We're leaning towards using it for everything along with Fabric and I'll show you examples. The core concepts, there are lots of them, so I'm just going to skip over.
20:04
In a nutshell, the three are playbook, play and tasks, at a very low level a task is the sort of granular thing that you see in yellow, this is off from their video. So some gotchas and best practices, you know, where do I put my Ansible code? So we've gone with, you know, the directory structure on the left, which you see, you know, high level there's a variant file author's license, Ansible client and Django project name.
20:24
Giant client is basically a Yeoman sort of Angular client, all front end code, Django is your Django project and then there's Ansible directory. Underneath Ansible you'll see, you know, there's dev and staging and production, those are basically the inventory files. The big directory to note there is the roles and that's the key, you don't want one
20:40
giant Ansible file, you want to basically follow this kind of structure and have things in roles. What's inside roles? So yeah, so that's the directory structure, the middle one is basically the roles. So Django, Python, uWSGI, virtual end, these are very composable roles. So you could swap out uWSGI for G unicorn, not a problem, so just get the G unicorn role. You can swap out Nginx or Apache, swap it out.
21:02
Virtual end is its own role, anything under Django will basically be very Django specific, anything under virtual end will be virtual end specific. If you're using Flask you can ignore the Django role, et cetera, et cetera. So you can basically build these roles and within these roles, as you can see on the right, under the uWSGI role there are handlers, tasks, templates and vars. I can't cover all of them, but the main one is tasks, that's where all your tasks go.
21:23
The templates are basically very interesting, there's the uWSGI.ini template, instead of having different templates in your code base for staging, production, et cetera, you can have one template, it's a Jinja template, as you can see, and then use variables. So what are some of the best practices? User modules, they have lots of modules, I've mentioned some of them here, pip and Django manage being the two ones.
21:43
What are the alternatives? You could use the shell and command module and then go raw, but then you'll end up doing basically what you're doing with fabric, right? So you might as well leverage the modules that they have, they're pretty flexible, here's the Django manage modules for example, you can specify the app path, the virtual end, the command, and also the settings you want to use.
22:01
And as you can see I'm using variables here, so there's almost nothing here that's specific to dev, staging, production or any other environment. Use variables, there are group variables, there are environment variables, there are lots of variables, it'll save you a lot of time, so if you're actually changing your code or anything, or you're adding another environment, all you have to do is add another file or two, and then you're good to go.
22:21
So as you can see I've defined where my virtual end is, it might be different from dev versus production, so you can accommodate for that. Use templates, don't have multiple files for your uviski or your Apache or nginx settings, et cetera, use templates, and these are Jinja templates, and they get compiled and put in certain places in runtime.
22:42
Use fax, this is a great Ansible thing, basically when it connects to a server, it gathers fax, fax could be in a number of processor cores, so for example in your nginx settings, you don't want to hard code the number of processors or listeners, it's just based on the server, so if you're upgrading your server, these will automatically change. You can still leverage Fabric, and you know, so for example you want to have a fab bootstrap command where we bootstrap our local
23:04
development system, so you could still use Fabric, but underneath it's calling that big Ansible command which you never want to call by hand. The same thing, you can deploy it by Fabric, again a big Ansible command, but it's hidden in your Fabric file, you still continue staying fab staging launch, and it'll launch to Fabric, launch to production. This GitHub repository there is really nice, some other articles, there's analysis by Lyft, why they work
23:26
with Stultstack sadly, and that is the end, and that's where the presentation is, thank you very much. I'm going to tell you about this thing called Hendrix. It's a framework for deploying Django apps that was
23:46
developed by these people right here at this company called Reelio.com, where it is currently being used in production. I'm here because they hired me to implement some asynchronous stuff and Celery, and when I got to work, that
24:03
guy Justin over there basically like threw himself in front of me and was like, don't do Celery, try this instead. And I was like, are you crazy? So I did, and now I'm converted, and I think everybody should know about this thing. So, Hendrix. It's basically Django plus Twisted, that's the idea with the name, or so I've been told.
24:28
What is it? It is essentially, it goes in the pipeline where you normally use Gunicorn, or Uwhiskey, however you say that. And it is a Twisted wrapper for that process, so instead of using greenlets or
24:47
whatever it is that Uwhiskey does, it uses Twisted to handle that whole thread pool, etc. If you don't know what Twisted is, from their webpage, it is an event-driven networking engine written in Python, and it's really amazing.
25:03
The more I learn about it, the more impressed I am. So, easier Django development and deployment with benefits. Why is it easier? A couple of little things, like when you're running the dev server, you don't have to do that if debug, then serve my statics from here.
25:23
Hendrix has a nice little way of doing that. You also don't need symlinks for your admin anymore, it just works now, which is kind of nice. And another bonus is that you get, you can just make a self-signed certificate and run SSL right there in the Django dev server, which is very handy sometimes.
25:45
In production, because Twisted has its own thread management, you don't need to do your unicorn, how many workers, conf file, stuff like that. So, we have a little upstart config that you can just, it's actually made for Ansible, so
26:02
it has the template brackets and you just use it and Ansible pops it in the right place. And you can just, this is actually a typo right here, it should be, I think it's Hendrix start, I don't remember, it's basically an Ubuntu service thing. There should be a pseudo in there too. So, but the good stuff is really what Twisted brings to the table. By running a Django app in Twisted, at DjangoCon I've seen a
26:28
lot of people with a lot of different ways for dealing with some of these problems that Hendrix really kind of, has for me, solved. Web sockets, deferred threads that normally, like stuff that you don't want to run in the request
26:43
cycle, you can just defer it, do it over here, don't have to use Celery all the time. Asynchronous IO for doing, well, let me just go through some examples. Web sockets, real time communication, you can do chat clients, or chat servers, you can do, I did some games, like, it's super fun,
27:04
you can write to your ORM right there in a socket call, and you don't have to run node, which is kind of nice sometimes. Here's a little example of doing a deferred thread, like this is a pattern I see constantly where you want to send an email.
27:23
The right way to do that is usually to have Celery do it so that the user doesn't have to wait for it, but now you can just defer it to a separate thread, update, do something that takes 10 seconds in a separate thread, go back to the user instantly. Yeah, so, I still haven't installed Celery at Reelio, strangely.
27:47
This use case is where you have, like, you have to go hit some API, it takes a second or two, you can basically set them all up instantly, and then you're back to doing something else.
28:01
It's a little callback-y, but it's something that you have to get used to once in a while. And the basic functionality, which is serving your web app, it's a little bit scary doing something totally that nobody else seems to be doing, but so far, so good. And one of the reasons that we wanted to show everyone is hopefully someone
28:23
will find some problem with it before the wrong time for finding problems with things. In the future, it's still in development, we're kind of trying to solidify some conventions, get some tests going, prove that it really is a viable way to do things, because it really does seem too good to be true, and some little details are still being refined.
28:47
We'll have the readme tidied up by end of day today, I promise. Oh good, I'm almost done. Pip install Hendrix. And that's it. Thanks a lot.
29:03
So I'm also from Tivix, and at Tivix we've had a number of projects over the past year and a half where we've been using Django and AngularJS together to come up with single-page apps. And so I wanted to take a few minutes to just sort of share some of our insights and what our experience was in putting that all together.
29:25
So just wanted to say thanks to Nina for her talks on Django REST Framework and AngularJS earlier this week. And we'll move on. If you want to follow along, it's public slides, you can go and visit them now.
29:43
So AngularJS and Django work really, really well together. Really like it. But you really also need to keep their roles well-defined and separated. We had started with a sort of mixed configuration where we had Django templates and pages actually driving the AngularJS implementation.
30:09
And that was kind of messy and difficult to really organize and have working productively. We then progressed to a website where it primarily just consumed JSONP content from a Tasty Pie API.
30:27
And that was better, but as I'm sure you're all well aware, JSONP has some rather significant limitations. So step in the right direction. But what we ultimately settled on was actually using Django REST Framework to provide all the content and interactions between the website and Django.
30:47
So you need to give them both their space. They will work together well, but don't mix those up too much or you're going to end up with StrangularJS, which is what we like to call it sometimes.
31:00
So yeah, going forward, we're only using Django REST Framework and AngularJS in that configuration. They are completely separate. We just have the calls back and forth. We do not have Django defining any templates up front. The single page app is just a collection of HTML files and assets that have been optimized.
31:24
So how did we get there? We've been treating AngularJS as a platform. So think of it as like you're developing an iOS app. You don't go into developing an iOS app by saying, now how am I going to have Django generate my views and controllers and all of that?
31:40
No. Think of them being completely separate. As a result, you need to utilize separate tools from Django and Python. So for us, we've been using Grunt quite extensively as well as Yeoman. Furthermore, if you're going to be building an API for mobile apps or for your website,
32:01
just do that all up front when you're going to put together your single page app. Don't put it off. Don't put off aspects of it. Make sure your API is all fleshed out, you've got validation, and everything can be done from there. You'll really reap the benefits later when you do go to mobile and it's all ready to go.
32:22
So this is a quick diagram of our stack that we utilize to develop and deploy Django REST framework. We use Nginx in combination with AngularJS, Yeoman, Bower. That all goes towards the end result, which is this nice and tidy set of assets.
32:47
So during development, what we'll do is we'll use Yeoman to actually scaffold out the project. This is nice as a good way to avoid StranglerJS, which is to let Yeoman make opinions about how this should work up front.
33:03
Defer to its directory structure, utilize the Grunt job that it has set up, and just, once again, avoid mixing Django and AngularJS. Just keep them separate. We moved on to using Grunt serve to actually manage them in parallel.
33:27
And that got messy because we add cores and we also had to write code that accommodated that. That wasn't great. So we're just serving it as static content on the same domain, and that works nicely. There are some caveats, but not a big deal. Deployment. Once again, don't use Django to deploy it.
33:42
Use Grunt and Gulp to actually build and deploy the assets. Utilize those tools as much as possible to crunch it down. So if you want to check out some code we've written, we're at github.com slash tivx. We've written Django rest off, which integrates the authentication tools with Django in a
34:01
RESTful interface, as well as an AngularJS module that interfaces with all that nicely. So once again, there's the URL for the slides, and thank you for a great conference. After Eric's close talk, why Django sucks, Django still sucks.
34:21
To my way of thinking, it sucks primarily because it still thinks of itself as an Apache plugin rather than a Python library. This is evidenced most clearly by the configure method of the lazy settings object. So what is the onSettings project? It's an effort to change project-wide settings from a globally incorporated single entity, you know, Django dot com dot settings, to a set of individually injected objects configurable with a diverse and flexible variety of patterns.
34:46
Here's a quick example. This is how you send mail with Django, right? An exceedingly simple task that Django happens to handle beautifully. Here's the documented approach. Import send mail and call it with its common sense dependencies injected. Of course, when we try to do that, we get an error because we haven't supplied the backend as a quad to the function.
35:03
Now in Python, this is called type error, or maybe in some cases attribute error, but in this other language called Django, it's improperly configured. This already betrays the underlying thinking on the matter because Django doesn't and can't know whether I've actually configured an email backend. It only knows whether I've supplied it to the function. Fortunately, Django is Pythonic enough to allow me to specify my own backend as a quarg, so I do.
35:25
You can see here that I also specify a file path to avoid getting another improperly configured. This isn't documented, but it actually works in the sense that it allows me to instantiate and obtain the backend object. However, even with a properly instantiated backend object, watch what happens. This is the end of the road.
35:41
I can't tell send mail about default charset, and since I haven't run settings dot configure, Django is essentially being rejected at this point. I can go no further. Now I don't know about you, but I run into this problem constantly. It's especially burdensome for a project like Hendrix, which Jamin just talked about, because Hendrix tries to import Django and feed it to its own APIs, which is a perfectly reasonable thing for a Python library to do.
36:03
Now it might be an apt metaphor to think of on settings as the third and final phase of Django's puberty. Prior to magic removal, Django was a child. Starting at about 1.4, it experienced a sort of adolescence, and now it's truly coming of age. The first step was the custom auth.user model that shows that Django cares about its people.
36:23
Then migration shows that Django cares about its people's right to change our mind. Unsettings shows that the Django tribe does not treat its project as an Apache plugin, but as a feature-rich Python subculture. So what's the current state of Unsettings? In addition to myself, the project has two other active contributors, both of whom are very talented and thoughtful Pythonistas,
36:41
Skyler Duveen of WNYC and James Farrington at Slashroot. We've developed a decorator called Uses Settings. When applied to a function that uses the settings singleton, it allows injection of that setting as a quorg instead. Simple. Now how many of you have written parts of Django's internal APIs that use the settings singleton? A small number of us, right?
37:01
Those of you that aren't raising your hands will experience no change of behavior whatsoever from the implementation of our decorator. Now for those of us that are raising our hands, the Uses Settings decorator is actually a relief of many of the pains of maintaining and testing APIs that require settings. Here we crafted a poll request of 78 commits that indicate our vision for the implementation of this decorator. Of these, we think eight are ready for review today.
37:23
If these eight are merged, you'll be able to call, send mail, just as I tried to do, without raising an error. Now, the reasons that I think that this is really important is, of course it removes burdensome import logic, allowing you to send mail. Great. But it's also a signal to the Python community that says, We are you. We're a Python library.
37:41
We're a Python project, and we appreciate the norms of the larger Python tribe. More importantly than that, it's a single to new Django contributors that says, Your work belongs here, and it won't be locked away behind our configuration drama. There's a lot of Python developers with incredible logic to contribute to our project. And if they know that contributing it to our project means that anytime they want to use it,
38:00
they have to negotiate with the settings singleton, they might be less inclined to. And there's plenty of other projects where their logic can go. Now, there are a bunch of things that you all can do. I was on Elena's Django news podcast at PyCon. Give that a listen, and you can learn more, obviously, that I can tell you in five minutes. Look at our poll requests. See what you think.
38:21
Work on unsettings at the sprints. I'll probably be working on it at least a little, although I'll probably also work on Hendrix. Think of Django as a community and a movement, not just a product, and see if that starts to subtly change your view on the matter. And lobby your core team. Not that long ago, this was what felt to me an awfully controversial idea, but I'm now slowly hearing members of the core team, I think, tell me that they're coming around on it
38:45
and starting to see that this is a viable way forward. I'm really hopeful that it is, and I do intend to keep working on it. The first and second phases of Django's puberty, as I call it, are some of the finest work by Russell Keith-McGee and Andrew Godwin that I've seen in the open source movement.
39:00
I'm Justin Holmes. My email address is justin at justinhomes.com. My GitHub is github.com slash jmiles. This presentation was made with a little thing called Wheelman, which is a CoffeeScript library for creating persuasion through the scroll wheel. Feel free to check that out as well. Thank you very much.
39:23
Form factor is a mobile data collection platform. What actually is that? It's a Django-powered platform for easy collection and submission of data from any device. So think of a field worker who needs to, on their daily tasks,
39:42
they have to submit a form. They go from house to house. The form factor would allow them to do that from any device, which we'll get to. So how's it built? You build a form with Django. You define what your form is, and then using a rest framework through a set of APIs,
40:07
different forms are made available on any different platform, and these are the key words. They're being native forms. So simply define a form on your server with Django,
40:21
and then expose that, and you'll have, using our iOS, Android, and future JavaScript library, you'll see a native form render. So what was the challenge, and why did we do this? Why not just simply create an HTML form and then simply render it in a web view on iOS and Android?
40:44
And the reason for that is we wanted that kind of native field. The real problem is these people need to submit data, right? So it needs to be as seamless as possible. It can't be kind of a janky experience,
41:02
which we've experienced on HTML5 and using PhoneGap and whatnot. So these are all native forms, and we didn't want to reinvent the wheel. We're constantly building forms, and as you guys know, building forms are hard. You have to have custom validation for each field,
41:22
and it takes a lot of time. So we wanted something out of the box that you could simply just define, build it once on the backend, and then all the different clients listening will seamlessly update. This is a bit of modeling. So as we were building this, we thought why call it forms,
41:43
because we wanted forms to refer to some other piece of data we have. So we thought a bit more generic, and why not call it entity? A form is just a representation of that entity. So I'll get to the demo in the end, but an entity is something you actually define.
42:02
It's a thing, right? And then there's different entity attribute fields, and these each are different types. So your text field, select field, related, and your actual data is an instance. So these instances related to entities,
42:22
and then instance field, load generic foreign key to an entity attribute. So that was kind of a form factor platform I just discussed, but a lot of the core of what we used to build it will be open sourcing. And that will be Django app,
42:41
that allows you to create new entities, and then rest framework APIs allow you to create and edit these instances of these entities. And then iOS and Android code base that are hooked up with API, so you can simply just plug it in and start using it.
43:00
And then, as you can see, we have kind of an internal debate going on what we're going to use for the JavaScript framework. And what you guys can use to use a simple contact form, right, if you had an application, Android application, iOS application, you could simply just pull in our libraries
43:23
and pip install this form factor library, and you're pretty much good to go. So it's really that simple. You could build your own form factor or whatever else you want. So quick demo of this. This is it.
43:43
So this is me actually defining a entity right here. So let's give person a first name.
44:11
And all your validation you can actually define right here. And the mobile app will dynamically pick that up. So, all right, now the entity ID is 27.
44:28
So this is the simulator running. So there's our dynamic form that was just picked up. Simply submit it.
44:41
No alert, but it's there. And you can change orders, and it will pick it up in the app as well. That's great. I hate to cut you off, but we're over time. I need Jacob Burch.
45:04
The Lawrence Journal World offices in Lawrence, Kansas, which is really, really close to the middle of the country and really close to the middle of nowhere, Simon Wilson, Adrian Holovarti, and Jacob Kaplan Moss started what became Django. And actually exactly almost nine years ago,
45:24
a little over nine years ago, Adrian actually made the work they had been doing for the Journal World open source, thereby sort of giving me birth to Django. To celebrate this event, we who are in Lawrence, Kansas, are going to be throwing a birthday party.
45:43
What that entails, we don't know, and that's up to you, everyone in the room, and everyone in social media who can sign up right now on djangobirthday.com. Let us know if you're interested in visiting Lawrence, seeing a little bit of history, and having some fun. If we get a small amount of people,
46:01
we'll have a little party, we've got a lot of people, we'll throw a bigger party, and probably have some talks along with it. So there's the information. You can talk to Frank, you can talk to me, you can talk to Jeff, you can talk to Flavio. All of us are here if you have any ideas for it, and we'll be in Lawrence in about a year. That's it.
46:26
Tmux and Tmucil. Tmux is, this is just a tool talk. Tmux is a terminal multiplexer. How many people have used Tmux? Wow, I don't even need to be up here. Well, for the other half. If you have, for those who haven't,
46:42
if you've used GNU screen, it's kind of similar to that. And then I'll explain Tmucil after I show Tmux. So, wow, it's so small. So this is just my I term in Tmux.
47:02
It just allows me to create windows and panes. You can't actually even see the power shell at the bottom, but you can have lots of different windows, and each window can have panes. So I can separate the screen into two panes. I can separate it into three panes, et cetera.
47:22
And I can also do this on the, I can use it like you use new screen to connect to servers, and you, your session, your SSH session on the server is maintained. So, for example, I can connect to, this is actually one of our production servers. And as soon as I,
47:43
as soon as I SSH into it, you know, whatever server I had, or whatever session I had running before is still there. So I can go and I can look at whatever I was looking at earlier and kind of, oh yeah, that's what I was working on. That's where the problem was, right. And I use, I just use I term tabs,
48:04
as you can see at the top, to kind of have, I use that for separate sessions only, only when I'm connected to separate servers. And everything else can exist in Tmux. And then Tmucil allows you to just kind of save Tmux configuration. So if I want to work on a particular project,
48:22
I just say Tmucil, and say I want to work on my UREC project, then I hit say Tmucil UREC, and it just opens up my, you know, my four pane tile layout. And you can just specify commands that get run in each pane. So, you know, get status, get branches, so I can remember what branches there were,
48:41
a listing of the directory, et cetera. You can, you can specify whatever you want to run. And if I, let's see, since I can't, oh, so over on the left here, is just what the, what a Tmucil configuration file looks like. It's just YAML.
49:02
And so you, the important part is really the, so root is kind of the root directory, so it'll change directory into that directory in every pane. And then you just have a list of panes. Oh, you can give it a layout, so if you have a complicated layout, for example, I bought a $300 4K TV
49:21
that I've been using as a monitor, and it's really crappy in every way, except for the fact that it has 4,000 pixels. And so on that one, I have like this six or eight pane layout, and you just kind of, you can just put that in here, and it's beautiful. But as you can see, it's just really simple. I just tell it what commands to run in each pane,
49:41
and it just does it. We built it at PBS kits. So around January, we released a new version of our homepage.
50:03
Pretty fancy. Lots of pictures and everything. And it's responsive, so that's good when you change the viewport. It takes pixel density and everything into consideration and readjusts the layout. So if you're on a mobile phone, it'd really suck if you had to load all the source images,
50:22
cause that'd be several megabytes. So when your site's responsive, you gotta take some of this other stuff into consideration. Pretty overwhelming stuff. So in the beginning we were like, alright, we can use some of these solutions, but the first three at least,
50:42
you still have to stamp out those different sizes yourself. The front end piece of it, the JavaScript, and in the case of the picture element, the browser can take care of building the request so that it asks for the right size image. But you still have to make them. So my coworker Miguel was like, that's stupid.
51:03
It is. So we built Bates, which is the backend in Django, that does a lot of that automatically. So the other two solutions are actually pretty good. Adaptive images, it's built in PHP, and it uses a thin layer of front end that sets cookie hints so that the served image will be the right size
51:22
for whatever user agent detection the cookie supplies. And resource it is also very good I suppose, I never used it. I think you have to pay for it. It's a platform as a service, a software as a service. So here are some of the guiding philosophies for when we built our thing. We wanted to keep the markup as semantic as possible,
51:42
and we want to not really break anything that you might have on your page, like jQuery and other frameworks and whatnot. And we wanted to be pretty agnostic about what you might want to use as a backend. So if you don't like Django, just use the piece of JavaScript to make the request, or vice versa, if you want to write your own front end
52:02
to do your user agent detection and whatnot, build those rules yourself, use the Django backend as your image breaker, cool. There's the GitHub project. You can check it out. I will lunge and give you a chance to copy it down.
52:22
All right, so here's the Django backend. You just pip install baits. And here's the admin. There's a couple of things you need to configure. Like obviously you'd have to tell it where to fetch your images from, so there's the notion of origin, and then your image sizes. So that's just a width, a quality,
52:41
so you can compress it if you want to. And there's a name, short name. So on the front end, the way you would use this is you would include carson.js, and in your markup, your image tags, instead of setting your source attribute, you're going to set something called data carson source, and that's going to, that URL is built from a combination of the namespace,
53:01
which is the origin that you just set in the Django admin, and the other thing you just set, which is the, sorry, and the other part of this is the image path. So in other words, it's, and your origin is where you specify the domain. In this case, for PBS Kids, it's a kind of delivery network. But after that, what's the path it comes after?
53:21
And that's this part. So the other attribute, carson size, is the image profile that you define in the admin. So, you know, script tag include carson, and there's a method called init in the carson object. Right now, it's in the pbs.kids namespace, but we're probably going to factor that out.
53:43
You just initialize it whenever you want to. In this case, it's on document ready, but whatever. Other, some other features that are in here, there are two built-in sizes, so that mezzanine is the source size, and none is just, I don't want to serve this image at all, because I want to save bandwidth. Rules, so sometimes it's useful to determine
54:02
the size of your image in data carson size dynamically at runtime. So you can do that with a callback. It's just a function that you can supply to do that maybe based on some user agent detection or like capability detection. Event hooks are nice, so when images load,
54:21
you want to control how it's presented to the user, so maybe it's kind of faded in and whatnot. Carson done is the same thing but for all of the images, so maybe you want them all to fit in, fade in at the same time when they're done loading. The trade-off is now you've gotten rid of browser prefetch. That optimization in your browser, where it inspects source attributes
54:41
and gets the images beforehand, we don't have that anymore, unfortunately. Roadmap, better documentation. We're working on it. There's GitHub pages. Picture support, I'm out of time. Picture support and ad hoc sizes. Contact me for questions. Thank you.
55:05
So tomorrow we have the sprints and people are generally advised not to run before they can walk, which is a shame when other people are sprinting and you want to sprint too. So don't worry about what people say because like other people, you're probably full of good ideas
55:20
and have solutions to problems and want to collaborate and contribute to what we're doing and we want you to. But too often people lack technical expertise or they lack the collaboration expertise or they simply lack the confidence to become involved. And these are barriers preventing participation.
55:43
People want to commit but they're not sure how. So the workshop that I'll be running tomorrow on the first day of the sprints, it will run all day, will cover the four key tools that you need to get started and the process itself.
56:03
And generally I find that even people who are doing this for the very first time and they don't even need to be Python users will normally leave the workshop at the end of the day with a commit in Django's code base. It might be a very small one but it will be a bit something
56:21
you've got a very good chance of something getting in. I'll be there to help you. The other sprinters will be there to help you. Our colleagues in the Django project will also be online helping you. So if you've ever wondered what these sprints were about or you've wanted to commit to Django or another Python project,
56:44
come along to this. We'll work at the speed of the slowest person which is usually myself. It's not rocket science because rockets are useless in this kind of endeavour. And it'll be fun and you don't need to worry about being the slowest person in the room
57:00
or anything like that. Just come along and have fun. If it's too slow for you then you can just ignore it and I won't be in the least bit offended if you drop in or out and you might be able to help people who are going a little bit more slowly than you. So it's all online anyway. You don't have to come to the sprints to do it. There's a tutorial there. There's a repository for it
57:21
that you can help improve. You can come and find me on IRC or in real life. Drop me a line. Don't be afraid to commit. Thank you. I had two minutes left so I'm going to use the rest of my allocation.
57:40
Now, forgive me if you've seen this before. I know some of you have but I had one original idea in May 2013. I'm still waiting for another one. I'm going to milk this one for all that it's worth because we have to work with what we can get. So, relationships. There are 7 billion other people in this world.
58:03
Are you sure that you have chosen the right one for yourself? Because right now there's probably someone out there with whom you would have been happier than the imperfect person you are having an imperfect relationship with right now.
58:20
What's worse is that your chances of discovering the perfect person are almost nil. Simple arithmetic means that almost any choice you'll make is the wrong one. And also that you will fail in any attempt to make a better choice.
58:43
So stop worrying about making the right choice. Instead, commit to what you have already chosen and develop it into the best possible relationship for you. And the same goes for your relationship with the software
59:02
that you work with because there are 7 billion web frameworks and languages and platforms to choose from and anyone you choose will probably be imperfect and the wrong one. So stop trying to make the right choice and instead commit
59:22
to the project you have already chosen and help turn it into the best possible one for you. Thank you.