Rest Api
Rest Api
This means that once the client sent a request to the server, it
cannot update the request. Also, once a server responded, it forgets about the request and the web
page is independent. There is no shared storage between the client and the server. If the user
wants to change something small, for example the details of a filter of data that is requested, he
has to submit the request again and the server must start all over again to fetch the data and
respond with a new page that contains the new data.
Django Channels is a new piece in the Django ecosystem that allows us to solve a class of
problems that standard Django does not solve well: event-driven programming. Event-driven
programming is the best paradigm to use when a system has high input/output load, which goes
beyond normal HTTP request/response traffic. Chat systems fit in this, because people do not
talk by following a request/response pattern.
Django is a collection of components that are designed to work together, and they cover many
of the common areas of web development. An important aspect of Django is that many of its
components are independent and, therefore, can be used individually without having to load all
of them. Django is a framework that follows the model-template-view pattern, which is very
similar to the model-view-controller pattern that many other frameworks have. The model layer
represents the database layer, used for data storage. Django abstracts you from writing SQL
queries. Instead of SQL, you use Python objects, and the load/save operations are handled for
you.
Most websites have the possibility to log in to a private area, where you can see customizations
done for the user and data that may not be public.
Installed apps → This is the list of apps, both internal to Django and from external libraries,
that are loaded on startup. Django will initialize them, load and manage their models, and make
them available in the application registry.
Logging → is a fundamental part of applications. The goal of logging is to save time when
problems happen, and to do so you need to be able to track what is happening during runtime.
Logging is important both for development and for production sites.
Normally I don’t recommend running migrate on new projects until after a custom user model
has been configured. Otherwise Django will bind the database to the built-in User model which
is difficult to modify later on in the project.
In Django, a view is simply a Python function (or a class) that takes in a web request and returns
a web response. This response could be an HTML page, a redirect, a 404 error, or even a JSON
response in the context of an API. The `as_view()` method is a built-in Django method to
convert class#based views to function-based views which are needed for URL routing.
`name=‘api-view’` is the name we give this URL pattern. It’s useful for reverse URL matching.
APIs are programming interfaces that connect applications to each other, a database, or a
messaging system.
Sometimes, you might want a little bit of information—a movie rating, stock price, or product
availability—but what you need is available only in HTML pages, surrounded by ads and
extraneous content. You could extract what you’re looking for manually by doing the following:
1. Type the URL into your browser.
2. Wait for the remote page to load.
3. Look through the displayed page for the information you want.
4. Write it down somewhere.
5. Possibly repeat the process for related URLs.
However, it’s much more satisfying to automate some or all of these steps. An automated web
fetcher is called a crawler or spider. After the contents have been retrieved from the remote web
servers, a scraper parses it to find the needle in the haystack.
I suppose the first question you need to ask are what permissions do you need and what sort. By
what sort, I mean do you want Model- or Object-level. To clarify the difference say you have a
model Car. If you want to give permissions on all cars, then Model-level is appropriate, but if
you want to give permissions on a per-car basis you want Object-level. You may need both, and
this isn't a problem as we'll see.
For Model permissions, Django handles these for you... mostly. For each model Django will create
permissions in the form 'appname.permissionname_modelname'. If you have an app called 'drivers' with
the Car model then one permission would be 'drivers.delete_car'. The permissions that Django
automatically creates will be create, change, and delete. For some strange reason they decided not to
include read permissions from CRUD, you will have to do this yourself. Note that Django decided to
change CRUD's 'update' to 'change' for some reason. To add more permissions to a model, say read
permissions, you use the Meta class:
class Car( models.Model ):
# model stuff here
class Meta:
permissions = (
( "read_car", "Can read Car" ),
)
Note that permissions is a set of tuples, where the tuple items are the permission as described
above and a description of that permission. You don't have to follow the permname_modelname
convention but I usually stick with it.
Finally, to check permissions, you can use has_perm:
obj.has_perm( 'drivers.read_car' )
Where obj is either a User or Group instance. I think it is simpler to write a function for this:
def has_model_permissions( entity, model, perms, app ):
for p in perms:
if not entity.has_perm( "%s.%s_%s" % ( app, p, model.__name__ ) ):
return False
return True
Where entity is the object to check permissions on (Group or User), model is the instance of a model,
perms is a list of permissions as strings to check (e.g. ['read', 'change']), and app is the application name
as a string. To do the same check as has_perm above you'd call something like this:
result = has_model_permissions( myuser, mycar, ['read'], 'drivers' )
If you need to use object or row permissions (they mean the same thing), then Django can't really help
you by itself. The nice thing is that you can use both model and object permissions side-by-side. If you
want object permissions you'll have to either write your own (if using 1.2+) or find a project someone
else has written, one I like is django-objectpermissions from washingtontimes.
select_related('beacon')
Optimizes database queries by performing an SQL JOIN between Advertisement and Beacon
(since beacon is a ForeignKey). This ensures that when you access ad.beacon, no additional query is
needed.
Information providers always have a website, but those are targeted for human eyes, not
automation. If data is published only on a website, anyone who wants to access and structure the
data needs to write scrapers and rewrite them each time a page format changes. This is usually
tedious. In contrast, if a website offers an API to its data, the data becomes directly available to
client programs. APIs change less often than web page layouts, so client rewrites are less
common. A fast, clean data pipeline also makes it easier to build unforeseen but useful
combinations. In many ways, the easiest API is a web interface, but one that provides data in a
structured format such as JSON or XML rather than plain text or HTML. The API might be
minimal or a full-fledged RESTful API but it provides another outlet for those restless bytes.
Basic Authentication
How It Works:
The client sends an HTTP request with an Authorization header containing the
username and password encoded in Base64.
Format: Authorization: Basic
<Base64Encoded(username:password)>
The server decodes the credentials and verifies them against its database.
If valid, the server processes the request; otherwise, it denies access.
Advantages:
Simple to implement.
No state is maintained on the server (stateless).
Disadvantages:
The username and password are sent with every request (even if encoded, not
encrypted).
Relies on HTTPS to secure communication.
No session management; the client must re-authenticate for every request.
Use Cases:
Session Authentication
How It Works:
Requires server-side storage, which doesn’t scale well for large applications.
The session can expire, requiring re-authentication.
Cookies must be securely managed to prevent theft (e.g., via cross-site scripting attacks).
Use Cases:
Token Authentication
How It Works:
Mobile and single-page applications (SPAs) where the client handles state.
APIs requiring lightweight, stateless authentication.
Example:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoxLCJleHAiOjE2ODk0N
jQ0MDB9.dXiLIYFgN4sGd72JUpZowH_2fp3KwTtSg3JPj6o8ZnY
Advantages:
Comparison Table
Session Token
Feature Basic Authentication JWT Authentication
Authentication Authentication
Low (server-side
Scalability High High Very High
storage)
Testing or simple
Use Case Traditional web apps Mobile apps, APIs Scalable APIs, SPAs
apps
OAuth 2.0 operates using authorization flows. The most common flows are:
1. The client redirects the user to the authorization server for login.
2. The user logs in and authorizes the application.
3. The authorization server sends an authorization code to the client.
4. The client exchanges the code for an access token.
5. The client uses the access token to make authorized API calls.
B. Implicit Flow
Use Case: Front-end applications where tokens are directly issued to the client.
Steps:
1. The client sends its client ID and client secret to the authorization server.
2. The server verifies the client and returns an access token.
3. The client uses the token for API access.
For example:
Stateless
State Stateless Stateful Stateless Stateless
(tokens)
Scope &
None None None Customizable Fine-grained
Granularity
Delegated
No No No No Yes
Access
Possible via
Revocation Not Applicable Easy Moderate Challenging
scopes
Third-party
Use Case Simple APIs Web apps Mobile apps SPAs, APIs
integrations
For an API to handle more requests, it needs to utilize more servers, which costs more money.
web-hooks, a technique where the client both makes requests and listens for them, allowing the
server to easily push updates to it. it's sometimes very easy to extend the client's functionality to
also listen for requests, enabling two-way communication. In its simplest form, web-hooks
requires the client to provide a Callback URL where it can receive events, and the server to have
a place for a person to enter that Callback URL. Then, whenever something changes on the
server, the server can send a request to the client's Callback URL to let the client know about the
update. Changes happening on the server are sent instantly to the client, so you have true real-
time communication. Also, web-hooks are efficient since there is only one request per update.
Token-based authentication is a security mechanism for APIs where a client provides a token
instead of credentials. The client must include this token in the header of every subsequent
request to the server. The server validates the token to authorize or deny the request.
JWT is used for user authentication and is passed between the user and the server. The
full definition of the acronym is JSON Web Token. The way they work is to encode the
user identity and sign it digitally, making it an unforgeable token that identifies the user,
and the application can later control access for the user based on their identity.
A JWT is a string composed of the header, payload, and signature. Those three parts are
separated by a .. Here is an example:
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE1NjQ5ODI5OTcs
Im5iZiI6MTU2NDk4Mjk5NywianRpIjoiMGIzOTVlODQtNjFjMy00NjM3LTkwMzYtZjgyZDg
y
YTllNzc5IiwiZXhwIjoxNTY0OTgzODk3LCJpZGVudGl0eSI6MywiZnJlc2giOmZhbHNlLCJ
0eXBlIjoiYWNjZXNzIn0.t6F3cnAmbUXY_PwLnnBkKD3Z6aJNvIDQ6khMJWj9xZM
The header of the JWT contains the encryption type, "alg": "HS256", and the
encryption algorithm, "typ": "JWT". We can see this clearly if we base64 decode the
header string:
>>> import base64
>>> header = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9'
>>> base64.b64decode(header)
b'{"typ":"JWT","alg":"HS256"}'
The content of the payload part is arbitrary. It can be anything the developer likes. We
can put in it the user ID, nickname, and so on. When the application server receives this
token, it can base64 decode it and obtain the information inside. One important thing to
note is that this information is not encrypted, therefore it is not recommended to store
credit card details or passwords here:
>>> import base64
>>> payload = 'eyJpYXQiOjE1NjQ5ODI5OTcsIm5iZiI6MTU2NDk4Mjk5NywianRpI
joiMGIzOTVlODQtNjFjMy00NjM3LTkwMzYtZjgyZDgyYTllNzc5IiwiZXhwIjoxNTY0
OTgzODk3LCJpZGVudGl0eSI6MywiZnJlc2giOmZhbHNlLCJ0eXBlIjoiYWNjZXNzIn0'
>>> base64.b64decode(payload + '==')
b'{"iat":1564982997,"nbf":1564982997,"jti":"0b395e84-61c3-4637-9036-f82d82a9
e779","exp":1564983897,"identity":3,"fresh":false,"type":"access"}'
The secret part here is a signature created by the HS256 algorithm. The algorithm is
encrypting the encoded header and payload data with a secret key that is known by the
application server only. While anyone can modify the JWT content, that would result in
a different signature, thus the data integrity is protected.