Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simplify deployment chapter by using pythonanywhere "autoconfigure" script #1190

Merged
merged 14 commits into from
Feb 12, 2018

Conversation

hjwp
Copy link
Contributor

@hjwp hjwp commented Jan 5, 2018

Hey y'all. I've been working on an "autoconfigure" script that can use the PythonAnywhere API to do things like configure a web app, update the wsgi file, and so on.

This change essentially turns the old manual procedure of:

  1. starting a Bash console
  2. cloning the repo from github
  3. creating a virtualenv
  4. pip installing django into it
  5. running manage.py migrate to create the db
  6. creating the web app on the web tab
  7. linking the web app to the virtualenv
  8. editing the wsgi file
  9. reloading the web app

into the following:

  1. Create an API token
  2. Open a Bash console
  3. pip install --user pythonanywhere
  4. run pa_autoconfigure_django.py <my-github-url>

So that's hopefully a much shorter and less error-prone deployment chapter.

Disadvantages:

  • more "magic"
  • future deployments need to run "manage.py collectstatic" to update static files (updates to later chapters pending)

Copy link
Collaborator

@ekohl ekohl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall I will agree that setting up the deployment on python anywhere is too much work that's not actually that good (and useful) of an experience for a beginner. They should focus on the actual coding, not deployment.

That said, I'm not sure if this is the way to go just yet. How will it handle the python versions, django versions etc. Right now the latest django is 2.0 but the tutorial still uses 1.11. We have no requirements.txt.

There is also a merge conflict now.

$ tree my-first-blog
my-first-blog/
$ tree
yourusername.pythonanywhere.com/
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this is a good idea. Some might change it, some might not. In general things that can't be copy-pasted and don't add actual learning value should be avoided.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agreed. I was just adapting from the existing tree listing. Options:

  • remove the tree command altogether
  • tree *.pythonanywhere.com should pick up on any username
  • just tree with no arguments will probably be fine! since the blog repo will be the only folder in their account, that's all they would see, apart from our Readme.txt

that last seems like the easiest? I'll make that change unless y'all have another preference.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh, i see i had already implemented solution 3? so there is actually no copy-paste error possible here...

@@ -415,7 +415,7 @@ $ git push

{% filename %}command-line{% endfilename %}
```
$ cd my-first-blog
$ cd ~/yourusername.pythonanywhere.com
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you really want the include the domain there, you can use $USER instead of yourusername I think.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I hadn't thought of that! yes. although maybe a bit too much like magic?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the $USER.pythonanywhere.com change would definitely work, and it would work nicely for the places we use workon to activate the virtualenv as well.

it still feels a bit wrong to me somehow. both the cd and the workon will tab-complete, which should mitigate any copy-paste problems... But I'm happy to go with what y'all prefer on this one. Let me know and I'll make the change.

@@ -180,11 +181,27 @@ Then, in a [PythonAnywhere Bash console](https://www.pythonanywhere.com/consoles

{% filename %}command-line{% endfilename %}
```
$ cd my-first-blog
$ cd ~/yourusername.pythonanywhere.com
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here

@@ -199,7 +199,7 @@ $ git push

{% filename %}command-line{% endfilename %}
```
$ cd ~/my-first-blog
$ cd ~/yourusername.pythonanywhere.com
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here


{% filename %}PythonAnywhere command-line{% endfilename %}
```
$ pip3.6 install --user pythonanywhere
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How does --user behave when inside a virtual env? That will happen for some users.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is the very first command the user runs on PythonAnywhere. There is no virtualenv active at this point.

@hjwp
Copy link
Contributor Author

hjwp commented Jan 19, 2018

Hi @ekohl, thanks so much for taking a look!

  • re django versions, I could add a way to specify them at the command-line
  • happy to consider any other changes to the script, to make life easier for attendees.

more replies inline!

@hjwp
Copy link
Contributor Author

hjwp commented Jan 19, 2018

have thrown together a --django argument for the script: pythonanywhere/helper_scripts@d0b972a

@aniav
Copy link
Member

aniav commented Jan 19, 2018

@magul @das-g would you by any chance have a moment to look at these changes as well? 🙏 🚀

@hjwp
Copy link
Contributor Author

hjwp commented Jan 20, 2018

latest update:

  • have replaced all the command lines that include "yourusername" to use the $USER variable instead, which should prevent all copy-paste mistakes.

  • have pushed a new version of the pythonanywhere helper scripts that pins the autoconfigure script to django 1.x (if no requirements.txt specified).

I think that takes care of all @ekohl's suggestions/concerns. Keen for more feedback!

(i think it would be particularly good if someone other than me could actually go through it and try it "in real life", with a real repo and so on?)

@das-g
Copy link
Member

das-g commented Jan 21, 2018

Interesting. I don't have time to test the changed instructions right now, but I can probably review test them tomorrow evening CET.


{% filename %}PythonAnywhere command-line{% endfilename %}
```
$ git clone https://github.com/<your-github-username>/my-first-blog.git
$ pa_autoconfigure_django.py https://github.com/<your-github-username>/my-first-blog.git
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On a fresh pythonanywhere account (dasg2) with nothing done except for creating the API token, this failed for me:

22:06 ~ $ pip3.6 install --user pythonanywhere
Collecting pythonanywhere
  Downloading pythonanywhere-0.0.8.tar.gz
Requirement already satisfied: docopt in /usr/local/lib/python3.6/dist-packages (from pythonanywhere)
Requirement already satisfied: requests in /usr/local/lib/python3.6/dist-packages (from pythonanywhere)
Building wheels for collected packages: pythonanywhere
  Running setup.py bdist_wheel for pythonanywhere ... done
  Stored in directory: /home/dasg2/.cache/pip/wheels/51/a6/09/27a2fbf112b070661d9fcc722ddbb28501d822dd227d23fc4d
Successfully built pythonanywhere
Installing collected packages: pythonanywhere
Successfully installed pythonanywhere-0.0.8
22:08 ~ $ pa_autoconfigure_django.py https://github.com/das-g/my-second-blog
< Running API sanity checks >
   \
    ~<:>>>>>>>>>
< Creating web app via API >
   \
    ~<:>>>>>>>>>
Traceback (most recent call last):
  File "/home/dasg2/.local/bin/pa_autoconfigure_django.py", line 52, in <module>
    main(arguments['<git-repo-url>'], arguments['--domain'], arguments['--python'], nuke=arguments.get('--nuke'))
  File "/home/dasg2/.local/bin/pa_autoconfigure_django.py", line 33, in main
    project.create_webapp(nuke=nuke)
  File "/home/dasg2/.local/lib/python3.6/site-packages/pythonanywhere/project.py", line 28, in create_webapp
    self.webapp.create(self.python_version, self.virtualenv.path, self.project_path, nuke=nuke)
  File "/home/dasg2/.local/lib/python3.6/site-packages/pythonanywhere/api.py", line 90, in create
    raise Exception(f'PATCH to set virtualenv path via API failed, got {response}:{response.text}')
Exception: PATCH to set virtualenv path via API failed, got <Response [400]>:{"virtualenv_path":["Warning: No virtualenv detected at this path. Do you need 
to create it?"]}
22:10 ~ $

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if you want to give it another go, you can either create a fresh pythonanywhere account (das3?)

👍 Worked fine with pythonanywhere-0.0.9 (with the same steps as above, on another brand-new pythonanywhere account dasg3, i.e., as instructed in the tutorial as changed by this PR)

or do a pip3.6 install --user --upgrade pythonanywhere, and then use the --nuke flag to pa_autoconfigure_django.py.

I might try that later, but as long as this option isn't mentioned in the tutorial, I don't think it's relevant to this PR.

I'll also review the rest of the changed instructions in this PR, probably some time this evening.

incidentally, i used your repo for my test, and it's just showing me the blank django "it worked" page?

Just as expected! 😃

i think by the time attendees get to the deploy chapter they do have some kind of front page / urls.py entry, right?

Nope, we have them go the "deploy early, deploy often" way.
The only thing they have by then is slightly changed project settings, one model class (for Posts) and it's registration for /admin. (And some model instances in their local DB.)

Due to first introducing some general Internet and Web concepts and then teaching the participants some basic Python, this deploy chapter is already around halfway into the tutorial. Depending on the length of the workshop, this is often as far as participants get on-site. As the note at the top of the chapter explains, deploying in this "early" state of the project should also enable the participants to more easily finish the tutorial at home on their own, should they not be able to finish it during a workshop.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

great! glad it's working now. and thanks for the clarification re: the state of the repo at that point. that actually reminds me - I think the current instructions are missing the createsuperuser step. will amend them and add that later today, so you can test them this evening.

@hjwp
Copy link
Contributor Author

hjwp commented Jan 23, 2018 via email

@hjwp
Copy link
Contributor Author

hjwp commented Jan 23, 2018

OK that should be fixed now. Sorry about that. We have a test suite at work that will pick up this sort of issue automatically in future.

@hjwp
Copy link
Contributor Author

hjwp commented Jan 23, 2018

@das-g if you want to give it another go, you can either create a fresh pythonanywhere account (das3?) or do a pip3.6 install --user --upgrade pythonanywhere, and then use the --nuke flag to pa_autoconfigure_django.py. Maybe just creating a brand new account would be better/easier.

incidentally, i used your repo for my test, and it's just showing me the blank django "it worked" page? i think by the time attendees get to the deploy chapter they do have some kind of front page / urls.py entry, right?

@ekohl
Copy link
Collaborator

ekohl commented Jan 23, 2018

I wonder if a git style pythonanywhere script would be easier to understand (and not pollute $PATH with many scripts). pythonanywhere newsite --django=1.11 <github-url>

Personally I have good experiences with click to build these kinds of applications.

@das-g
Copy link
Member

das-g commented Jan 23, 2018

I guess by "git style" you mean a single (top-level) command with sub-commands for the various actions? (Other examples for that are pip, Django's django-admin and ./manage.py, and (like git) almost every modern CLI VCS.)

I think that'd be a good idea and worth a feature request at https://github.com/pythonanywhere/helper_scripts

@ekohl
Copy link
Collaborator

ekohl commented Jan 23, 2018

@hjwp
Copy link
Contributor Author

hjwp commented Jan 23, 2018 via email

@das-g
Copy link
Member

das-g commented Jan 23, 2018

can I assume you don't consider this a blocking issue as far as this PR is concerned?

I don't consider it blocking.

@ekohl
Copy link
Collaborator

ekohl commented Jan 23, 2018

This is code wise the only non-django dependency which makes it a big change and I'd like the experience to be consistent. If the UI would change at some point, the old instructions might break. Especially since some translations are not updated all the time it could end up broken.

@hjwp
Copy link
Contributor Author

hjwp commented Jan 23, 2018

@ekohl I'd be happy to commit to keeping the "legacy" version of the script (if that's what ends up in the djangogirls tutorial) for as long as it takes for y'all to update all the languages to a new command-line version.

@hjwp
Copy link
Contributor Author

hjwp commented Jan 23, 2018

OK the createsuperuser is back. It requires manually activating the virtualenv and cd ing into the project directory. If I get a moment I'll see whether this is something the autoconfigure script could do for the user... (it might not be totally straightforward, i think the executable would have to become a bash script, but we'll see...)

@aniav
Copy link
Member

aniav commented Jan 23, 2018

Jest a note that I will want to add the previous version of this chapter, the manual one, to the tutorial-extensions book, so when someone will want to dig in how to do stuff by hand they will be able to do so as well :)

@hjwp
Copy link
Contributor Author

hjwp commented Jan 23, 2018

@aniav good idea! i'd be happy to help with that :)

@aniav
Copy link
Member

aniav commented Jan 23, 2018

👍 for any pull requests about that 🎉

├── __init__.py
├── settings.py
├── urls.py
└── wsgi.py
```
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The output of tree is now much larger than shown in the tutorial:

18 directories, 84 files (click to expand)

.
├── README.txt
└── dasg3.pythonanywhere.com
    ├── blog
    │   ├── __init__.py
    │   ├── __pycache__
    │   │   ├── __init__.cpython-36.pyc
    │   │   ├── admin.cpython-36.pyc
    │   │   └── models.cpython-36.pyc
    │   ├── admin.py
    │   ├── apps.py
    │   ├── migrations
    │   │   ├── 0001_initial.py
    │   │   ├── __init__.py
    │   │   └── __pycache__
    │   │       ├── 0001_initial.cpython-36.pyc
    │   │       └── __init__.cpython-36.pyc
    │   ├── models.py
    │   ├── tests.py
    │   └── views.py
    ├── db.sqlite3
    ├── manage.py
    ├── mysite
    │   ├── __init__.py
    │   ├── __pycache__
    │   │   ├── __init__.cpython-36.pyc
    │   │   ├── settings.cpython-36.pyc
    │   │   └── urls.cpython-36.pyc
    │   ├── settings.py
    │   ├── urls.py
    │   └── wsgi.py
    └── static
        └── admin
            ├── css
            │   ├── base.css
            │   ├── changelists.css
            │   ├── dashboard.css
            │   ├── fonts.css
            │   ├── forms.css
            │   ├── login.css
            │   ├── rtl.css
            │   └── widgets.css
            ├── fonts
            │   ├── LICENSE.txt
            │   ├── README.txt
            │   ├── Roboto-Bold-webfont.woff
            │   ├── Roboto-Light-webfont.woff
            │   └── Roboto-Regular-webfont.woff
            ├── img
            │   ├── LICENSE
            │   ├── README.txt
            │   ├── calendar-icons.svg
            │   ├── gis
            │   │   ├── move_vertex_off.svg
            │   │   └── move_vertex_on.svg
            │   ├── icon-addlink.svg
            │   ├── icon-alert.svg
            │   ├── icon-calendar.svg
            │   ├── icon-changelink.svg
            │   ├── icon-clock.svg
            │   ├── icon-deletelink.svg
            │   ├── icon-no.svg
            │   ├── icon-unknown-alt.svg
            │   ├── icon-unknown.svg
            │   ├── icon-yes.svg
            │   ├── inline-delete.svg
            │   ├── search.svg
            │   ├── selector-icons.svg
            │   ├── sorting-icons.svg
            │   ├── tooltag-add.svg
            │   └── tooltag-arrowright.svg
            └── js
                ├── SelectBox.js
                ├── SelectFilter2.js
                ├── actions.js
                ├── actions.min.js
                ├── admin
                │   ├── DateTimeShortcuts.js
                │   └── RelatedObjectLookups.js
                ├── calendar.js
                ├── cancel.js
                ├── change_form.js
                ├── collapse.js
                ├── collapse.min.js
                ├── core.js
                ├── inlines.js
                ├── inlines.min.js
                ├── jquery.init.js
                ├── popup_response.js
                ├── prepopulate.js
                ├── prepopulate.min.js
                ├── prepopulate_init.js
                ├── timeparse.js
                ├── urlify.js
                └── vendor
                    ├── jquery
                    │   ├── LICENSE-JQUERY.txt
                    │   ├── jquery.js
                    │   └── jquery.min.js
                    └── xregexp
                        ├── LICENSE-XREGEXP.txt
                        ├── xregexp.js
                        └── xregexp.min.js

18 directories, 84 files


Maybe we should ignore some stuff with -I, e.g. tree -I 'static|__pycache__'? Though that would need some explanation, too.

Copy link
Contributor Author

@hjwp hjwp Jan 24, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

well spotted. tree -L 3 also produces a reasonably sane amount of output.

tree -L 3 -- 22 directories, 93 files
$ tree -L 3
.
├── blog
│   ├── __init__.py
│   ├── __pycache__
│   │   ├── __init__.cpython-36.pyc
│   │   ├── [...]
│   ├── admin.py
│   ├── forms.py
│   ├── migrations
│   │   ├── 0001_initial.py
│   │   ├── __init__.py
│   │   └── __pycache__
│   ├── models.py
│   ├── static
│   │   └── css
│   ├── templates
│   │   └── blog
│   ├── tests.py
│   ├── urls.py
│   └── views.py
├── db.sqlite3
├── manage.py
├── mysite
│   ├── __init__.py
│   ├── __pycache__
│   │   ├── __init__.cpython-36.pyc
│   │   ├── [...]
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
└── static
    ├── admin
    │   ├── css
    │   ├── fonts
    │   ├── img
    │   └── js
    └── css
        └── blog.css

I'm not sure we really want to dive into an explanation of tree arguments though? How about just using ls:

$ ls
blog  db.sqlite3  manage.py  mysite  static
$ ls blog/
__init__.py  __pycache__  admin.py  forms.py  migrations  models.py  static
templates  tests.py  urls.py  views.py

that seems simpler, maybe just go with that for now?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, good call. 👍

ls has been introduced (at least to UNIXoid users) in Introduction to the command-line interface, so let's stick to that.

<!--TODO: think about using requirements.txt instead of pip install.-->
On PythonAnywhere all those steps are automated, but they're the same steps you
would have to go through with any other server provider. The main thing to notice
right now is that your database on PythonAnywhere is actually totally separate from
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 This phrasing is better than the original one, as "separate" makes the point more clearly than "different". (Judging from the questions we get on https://gitter.im/DjangoGirls/tutorial, this often lead to confusion or misconceptions.)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks!

On PythonAnywhere all those steps are automated, but they're the same steps you
would have to go through with any other server provider. The main thing to notice
right now is that your database on PythonAnywhere is actually totally separate from
your database on your own PC -- that means it can have different posts and admin accounts.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will GitBook show this -- as an mdash (—) or ndash (–) or so, instead of a double-minus/dash? (The GitHub preview shows it as the latter.)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll replace it with an explict mdash literal just in case.

[...]
Applying sessions.0001_initial... OK
(mvenv) $ python manage.py createsuperuser
$ workon $USER.pythonanywhere.com
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can never remember which non-whitespace characters terminate a shell variable name and which don't, so when doing something like this myself, I prefer to use the ${variable_name} syntax whenever a variable is interpolated into a larger "word" (command or argument):

workon ${USER}.pythonanywhere.com

But maybe that's just me, and to most of our participants this will be rather "magic" anyway (as we AFAIK don't introduce shell variables to them anywhere in the tutorial).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I couldn't tell you about shell variable name termination either, but in any case this one works. I'm still a bit uncomfortable about the magic here. We could revert back to just using "yourusername.pythonanywhere.com"? It has the benefit of teaching people that, when they copy and paste instructions from the internet, they always have to look out for any placeholder strings they need to substitute... Happy either way tbh.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we just mention that bash will substitute the username for ${USER} (or for $USER if we leave it at that), and that in the pythonanywhere console, the username is the pythonanywhere account name? We can make that (more specific, but still correct) claim without introducing environment variables / shell variables in general.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes! or at least, let's at least give it a try, then we can take a view as to whether we're throwing too many distracting explanations around...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, I've done that. I am a bit worried that we're spending a lot of time explaining some stuff that's not really core to either the deployment, or pythonanywhere.

Maybe we need to take a step back, or ask someone else to have a fresh pair of eyes on it?

I don't know. It'll work, and we will definitely get the benefit of avoiding copy-paste errors, but I worry that adding the $USER thing, and then laboriously explaining it, is one level of complication and distraction too many. Surely attendees are used to substituting usernames by now? Or surely that's a more important skill to teach than explaining what $USER is?

(in the ORM chapter for example, we expect people to substitute User.objects.get(username='ola') appropriately...)

[...]
Applying sessions.0001_initial... OK
(mvenv) $ python manage.py createsuperuser
$ workon $USER.pythonanywhere.com
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it OK to use the workon command (from virtualenvwrapper, isn't it?) without introducing it first? Though, to manually source the activate script, we would have to know where the magic script has placed the virtualenv it created ...

Maybe add a short explanation that this does the same as the source myvenv/bin/activate we did locally.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think at least a short explanation would be a good idea yes. I'll add one.

(workon is from virtualenvwrapper yes. we quite like virtualenvwrapper at pythonanywhere, because it puts all the virtualenvs in a sensible place, and it encourages you to give them all sensible names -- in this case, we name them after the site they're working on. i think one of the problems with "manual" virtualenv creation is that they tend to all end up named "myenv" or "venv" or "virtualenv", and then you can't actually tell at a glance what you're working on...)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about I look into whether we could drop virtualenvwrapper for the autoconfigure script, and just have a "normal" virtualenv folder, in the same folder as the source code folder? maybe a --virtualenv-name command line arg, then we can set it to "myenv", and it will be exactly like on the users' own laptop?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It makes me wonder: would it be possible to fully abstract the pythonanywhere setup behind a script? Including pulling. That way we don't need to explain it and skipping would be easy as well. It's a comment I heard a few times: deployment to pythonanywhere is nice, but doesn't add a lot of value in terms of learning. A lot of duplicated steps. It is nice that they can actually go there on their phones so the end result is certainly nice but in a time of PaaS and even more modern alternatives, should we really start with teaching about hosting? The basics of web development are hard enough as it is.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would it be possible to fully abstract the pythonanywhere setup behind a script? Including pulling.

The pa_autoconfigure_django.py tool introduced with this change does that, doesn't it? (Assuming that by "pulling" you mean pulling the git repo from GitHub to pythonanywhere.)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

finally, re: "vanilla" virtualenv vs virtualenvwrapper, the suggestion that we "hack" virtualenvwrapper by changing $WORKON_HOME in order to essentially force it to create something that looks like a vanilla virtualenv ends up removing all of the reasons to use virtualenvwrapper I think, so I'm -1 on that.

but I think we could definitely consider the option of adding a --no-virtualenvwrapper argument to the script (or maybe, heck, just a --djangogirls arguement) in order to make the virtualenv setup on pythonanywhere look more like the virtualenv on the users' laptop.

yes the script is intended to be useful for people outside of djangogirls, but djangogirls is my first target market, and it's more important to me to make y'all happy first, and I can worry about other people later.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if a nice way to sidestep this issue for now would be to have the pa_autoconfigure_django.py script automatically drop people into a shell with the virtualenv active and cd'd into the right directory? that's something that would be useful for almost anyone, and I think I know how to do it... Will take a look now.

Copy link
Member

@das-g das-g Jan 24, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

finally, re: "vanilla" virtualenv vs virtualenvwrapper, the suggestion that we "hack" virtualenvwrapper by changing $WORKON_HOME in order to essentially force it to create something that looks like a vanilla virtualenv ends up removing all of the reasons to use virtualenvwrapper I think, so I'm -1 on that.

What I meant was to do that

  1. only temporarily (for the invocation of virtualenvwrapper in pa_autoconfigure_django.py)
    and
  2. only when explicitly requested (i.e. when pa_autoconfigure_django.py is called with a CLI option towards that end)

Thus

pa_autoconfigure_django.py https://github.com/<your-github-username>/some-django-project.git

would have the same behavior as it currently has, and for the tutorial, we'd do something like

pa_autoconfigure_django.py https://github.com/<your-github-username>/my-first-blog.git --virtualenv-name myvenv --workon-home .

or even

WORKON_HOME="." pa_autoconfigure_django.py https://github.com/<your-github-username>/my-first-blog.git --virtualenv-name myvenv

I wonder if a nice way to sidestep this issue for now would be to have the pa_autoconfigure_django.py script automatically drop people into a shell with the virtualenv active and cd'd into the right directory?

👍 Yeah, if that's workable, it's probably an even better approach.

✨ Hide the magic behind sufficiently advanced technology, so it won't unsettle anyone. ✨

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:) working on said magic now 🎩

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK magic done!

Applying sessions.0001_initial... OK
(mvenv) $ python manage.py createsuperuser
$ workon $USER.pythonanywhere.com
(yourusername.pythonanywhere.com) $ cd $USER.pythonanywhere.com
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dito w.r.t. variable interpolation

@@ -4,4 +4,5 @@ Next, it's time to sign up for a free "Beginner" account on PythonAnywhere.
* [www.pythonanywhere.com](https://www.pythonanywhere.com/)



Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why the added blank line?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no idea. have removed it again.

- Downloading your code from GitHub
- Creating a virtualenv on PythonAnywhere, just like the one on your own PC
- Updating your settings file with some deployment settings
- Setting up a database on PythonAnywhere using the "migrate" command
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd use inline code markup instead of quotes here, and prepend manage.py:

  • Setting up a database on PythonAnywhere using the manage.py migrate command

@hjwp
Copy link
Contributor Author

hjwp commented Jan 24, 2018

the more I think about this $USER thing, the more I'm seeing its disadvantages rather than advantages. It looks weird, so we end up having to explain it, and now we're ending up teaching the user about shell variables, and all this to avoid a possible copy-paste error. Surely it's more valuable to teach people "when you copy and paste stuff you see on the internet, and you see something that says <your-username-here>, then you need to substitute in your actual username? Surely that's a more valuable programming-life-skill to teach than shell variables?

bearing in mind we're already telling them to do this with <your-github-username> in this very same chapter!

so unless someone has a strong objection, I'm going to switch the $USERs to <your-pythonanywhere-username>. at least for now. hey, if we flip-flop and change our minds on it, it's easy to switch back 😉

@hjwp
Copy link
Contributor Author

hjwp commented Jan 24, 2018

all right everyone, we have an updated version that doesn't require the reader to use workon, or cd into a directory manually (although they might need to later if they have closed their console and are reopening a new one, so I've added an explanation about that to later chapters).

I'm happy to draft a djangogirls-extensions chapter that explains how to do everything manually, so that readers (and perhaps coaches) can find out more about what's actually going on behind the scenes. Let me know if y'all consider that a blocking issue?

other than that, I think all major concerns so far have been addressed? Would it be good to get another fresh pair of eyes on it?

Copy link
Contributor Author

@hjwp hjwp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ekohl are you happy that all your requested changes have been incorporated?

Copy link
Member

@das-g das-g left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMHO almost ready to ship! 🚢


> **Note** PythonAnywhere is based on Linux, so if you're on Windows, the console will look a little different from the one on your computer.

Deploying a web app on PythonAnywhere involves pulling down your code from GitHub, and then configuring PythonAnywhere to recognise it and start serving it as a web application. There are manual ways of doing it, but PythonAnywhere provide a helper tool that will do it all for you. Let's install it first:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/provide/provides/, as "PythonAnywhere" seems to be singular, not plural (as seen by the "is" in the note above).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yep!

Here's another thing that's different between your own computer and the server: it uses a different database. So the user accounts and posts can be different on the server and on your computer.

Just as we did on your own computer, we repeat the step to initialize the database on the server, with `migrate` and `createsuperuser`:
As a result, just as we did on your own computer, we repeat the step to
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While it can be concluded that we have to repeat that step, doing so is not a "result" of what was mentioned above. As a result,Thus, maybe use

Thus, [...]

instead of

As a result, [...]

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can i disagree with this? to me the meaning of "as a result" is almost exactly the same as "thus". we have to run createsuperuser again because the database is separate / as a result of the fact that the database is seperate / the database is seperate, thus we have to run createsuperuser again. they all mean the same thing to me.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, then maybe include the "have to":

As a result, just as we did on your own computer, we have to repeat the step to [...]

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

never mind, I now see you already changed it to "need to", which is just as fine to make to logic work out


> **Note** Make sure you choose the "Manual configuration" option, not the "Django" one. We're too cool for the default PythonAnywhere Django setup. ;-)
Now, if you like you can also take a look at your code on PythonAnywhere using
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure (as I'm not a native speaker of English): Wouldn't a comma belong after the "if you like"?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yep, that'd be a good comma i think.

@ekohl
Copy link
Collaborator

ekohl commented Jan 25, 2018

Due to $job I have very little time to look at this right now. Hopefully next week because otherwise it'll likely be mid February due to conferences.

Copy link
Member

@das-g das-g left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit: Looks good to me, now. 👍

@hjwp
Copy link
Contributor Author

hjwp commented Jan 25, 2018

@aniav have done a first cut of the manual deployment as an extension: DjangoGirls/tutorial-extensions#99

@keikoro
Copy link

keikoro commented Feb 2, 2018

Heya, will this work with other shells, too?

@hjwp
Copy link
Contributor Author

hjwp commented Feb 2, 2018

@kerstin - the pa_autoconfigure.py script will only work from a PythonAnywhere Bash console, it's not currently something you can use from your own computer.

@keikoro
Copy link

keikoro commented Feb 2, 2018

@hjwp Ah, sorry, seems like a misunderstood when I read through the original issue (I've not tried PA yet, always stuck to Heroku), thanks for clearing this up!

@aniav
Copy link
Member

aniav commented Feb 11, 2018

All good! I approve of these changes and I am happy all of you have given so much thought here. I will merge it tomorrow morning to not break anything in the middle of weekend workshops ❤️💪 🎉

@aniav aniav merged commit 44709ce into DjangoGirls:master Feb 12, 2018
@aniav
Copy link
Member

aniav commented Feb 12, 2018

🎉 🎉 🎉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants