32
loading...
This website collects cookies to deliver better user experience
Some reasons you might want to use REST framework:
- The Web browsable API is a huge usability win for your developers.
- Authentication policies including packages for OAuth1a and OAuth2.
- Serialization that supports both ORM and non-ORM data sources.
- Customizable all the way down - just use regular function-based views if you don't need the more powerful features.
- Extensive documentation, and great community support.
- Used and trusted by internationally recognised companies including Mozilla, Red Hat, Heroku, and Eventbrite.
Despite the benefits of location-smart, time-agile and cloud-clever applications, there’s been no good platform for building applications that work like this. This is what Fly has set out to fix. In the process we want to make application distribution platforms as ubiquitous as CDNs.
ss-api
for short, on fly. This will have the following features:fly
to manage this). This is especially nice for APIs and simplifies authentication to a token, which I prefer for microservices/ping/
, which connects to the DB and issues an innocuous select 1
statement to make sure things are workingdocker
with a Dockerfile
and gunicorn
to launch the app. The cool thing about fly is that you can give it a Dockerfile
and a fly.toml
and you have a full-fledged app running on their infrastructureusers
, that you can use to manage your users. You must be authenticated to see it. git clone [email protected]:zmallen/ss-api.git
docker compose up
and connect locally by navigating to:http://localhost:8000
docker-compose.yml
file overrides the RUN
command in the Dockerfile
by issuing the following command on every docker compose up
:command: bash -c "python manage.py migrate && python manage.py runserver 0.0.0.0:8000"
gunicorn
to serve the app and we run migrations manually./ping/
endpoint on Swagger. This is by design - the app will render endpoints based on permission, and under /ping/views.py
on Line 16, the permission for this endpoint is:permission_classes = (AllowAny,)
ssapi/views.py
, under the UserViewSet
on Line 17:authentication_classes = (authentication.TokenAuthentication,)
settings.py
Lines 88-111:# DRF settings
REST_FRAMEWORK = {
"DEFAULT_PERMISSION_CLASSES": ("rest_framework.permissions.IsAuthenticated",),
"DEFAULT_AUTHENTICATION_CLASSES": (
"rest_framework.authentication.TokenAuthentication",
),
"DEFAULT_RENDERER_CLASSES": ("rest_framework.renderers.JSONRenderer",),
}
# SWAGGER_SETTINGS
SWAGGER_SETTINGS = {
"USE_SESSION_AUTH": False,
"LOGIN_URL": "rest_framework:login",
"LOGOUT_URL": "rest_framework:logout",
"VALIDATOR_URL": None,
"SECURITY_DEFINITIONS": {
"api_key": {
"type": "apiKey",
"name": "Authorization",
"in": "header",
},
},
"REFETCH_SCHEMA_WITH_AUTH": True,
}
DRF_SETTINGS
, I forced TokenAuthentication
and isAuthenticated
for viewing endpoints, so no more sessions! 🎉🎉manage.py
comes into play.docker-compose.yml
:└> docker compose run api python manage.py getdevtoken
[+] Running 1/0
⠿ Container ss-api-db-1 Running 0.0s
Looking for superuser..
superuser doesn't exist, creating!
superuser created!
Use the following key for dev:
(。◕‿‿◕。)☞☞ Token 9884a551be31b80a61b49becf7c3640224a9ec42 ☜☜(。◕‿‿◕。)
Token abc
and navigate over to your browser, then click 'Authorize', paste and press submit. You should get the /users/
endpoint to return in the Swagger frontend, and issuing a GET request will list the superuser
!toml
file for fly. This is a configuration file used by fly to deploy your app. I generated one within the Github repo, but you can explore how to generate and configure other toml
files on fly here.DATABASE_URL
string fly secret
with the DATABASE_URL
from Step 1 so our app can dynamically render the secret in a fly environment and use the db created in step 1fly ssh
devtoken
for prodfly create
and name your app!└> fly create
? App Name: ssapiblog
automatically selected personal organization: Zack Allen
New app created: ssapiblog
fly
with fly postgres create
. Accept all the defaults (minimal DB settings, aka the cheapest!) and wait for fly to give you the DATABASE_URL
.└> fly postgres create
? App Name: ssapidb
Automatically selected personal organization: Zack Allen
? Select region: iad (Ashburn, Virginia (US))
? Select VM size: shared-cpu-1x - 256
? Volume size (GB): 10
Creating postgres cluster ssapidb in organization personal
Postgres cluster ssapidb created
Username: postgres
Password: SECRETPASSWORD
Hostname: ssapidb.internal
Proxy Port: 5432
PG Port: 5433
Save your credentials in a secure place, you won't be able to see them again!
Monitoring Deployment
...
...
2 desired, 2 placed, 2 healthy, 0 unhealthy [health checks: 6 total, 6 passing]
--> v0 deployed successfully
Connect to postgres
Any app within the personal organization can connect to postgres using the above credentials and the hostname "ssapidb.internal."
For example: postgres://postgres:[email protected]:5432
See the postgres docs for more information on next steps, managing postgres, connecting from outside fly: https://fly.io/docs/reference/postgres/
For example:
, which in this example is:postgres://postgres:[email protected]:5432
/ssapidb
at the end of the DATABASE_URL
fly secrets set DATABASE_URL="postgres://postgres:[email protected]:5432/ssapidb"
fly.toml
to whatever you want:app = "ssapiblog"
fly deploy
:└> fly deploy
Deploying ssapiblog
==> Validating app configuration
--> Validating app configuration done
Services
TCP 80/443 ⇢ 8000
==> Creating build context
--> Creating build context done
==> Building image with Docker
--> docker host: 20.10.8 linux x86_64
Sending build context to Docker daemon 153.1kB
...
==> A bunch of Docker output
You can detach the terminal anytime without stopping the deployment
Monitoring Deployment
v0 is being deployed
2021-12-30T22:26:21.000 [info] 145.40.89.203 - - [30/Dec/2021:22:26:21 +0000] "GET /ping/ HTTP/1.1" 500 114326 "http://172.19.10.66:8000/ping" "Consul Health Check"
1 desired, 1 placed, 0 healthy, 0 unhealthy [health checks: 2 total, 1 passing, 1 critical]
/ping
healthcheck is failing. This will most likely fail after a certain amount of time, so in a separate tab navigate to the project directory to run a few fly ssh
commands.ssapidb
database by running a handy dandy bash script I added into the repo. We can use this via fly ssh console -C
command:└> fly ssh console -C 'bash /app/provision_db.sh'
Connecting to ssapiblog.internal... complete
Database does not exist. Creating now..
CREATE DATABASE
fly logs
in a separate tab, you should see Consul health checks returning 200, which is healthy \o/:2021-12-30T22:31:27.116 app[3d7bc4b5] iad [info] 145.40.89.203 - - [30/Dec/2021:22:31:27 +0000] "GET /ping HTTP/1.1" 301 0 "-" "Consul Health Check"
2021-12-30T22:31:27.119 app[3d7bc4b5] iad [info] 145.40.89.203 - - [30/Dec/2021:22:31:27 +0000] "GET /ping/ HTTP/1.1" 200 2 "http://172.19.10.66:8000/ping" "Consul Health Check"
└> fly ssh console -C 'python /app/manage.py migrate'
Connecting to ssapiblog.internal... complete
Operations to perform:
Apply all migrations: admin, auth, authtoken, contenttypes, sessions
Running migrations:
Applying contenttypes.0001_initial... OK
Applying auth.0001_initial... OK
Applying admin.0001_initial... OK
Applying admin.0002_logentry_remove_auto_add... OK
Applying admin.0003_logentry_add_action_flag_choices... OK
Applying contenttypes.0002_remove_content_type_name... OK
Applying auth.0002_alter_permission_name_max_length... OK
Applying auth.0003_alter_user_email_max_length... OK
Applying auth.0004_alter_user_username_opts... OK
Applying auth.0005_alter_user_last_login_null... OK
Applying auth.0006_require_contenttypes_0002... OK
Applying auth.0007_alter_validators_add_error_messages... OK
Applying auth.0008_alter_user_username_max_length... OK
Applying auth.0009_alter_user_last_name_max_length... OK
Applying auth.0010_alter_group_name_max_length... OK
Applying auth.0011_update_proxy_permissions... OK
Applying auth.0012_alter_user_first_name_max_length... OK
Applying authtoken.0001_initial... OK
Applying authtoken.0002_auto_20160226_1747... OK
Applying authtoken.0003_tokenproxy... OK
Applying sessions.0001_initial... OK
└> fly ssh console -C 'python /app/manage.py getdevtoken'
Connecting to ssapiblog.internal... complete
Looking for superuser..
superuser doesn't exist, creating!
superuser created!
Use the following key for dev:
(。◕‿‿◕。)☞☞ Token TOKEN ☜☜(。◕‿‿◕。)
fly open
and go through the same workflow as your local deployment: put Token TOKEN
into the Authorize panel, and you can now see the authenticated users endpoint, and issue a GET request to get your token!POST
request endpoint here to create a new user. api/settings.py
file for other configuration options I used. ss-api
repo here: