Skip to content

Commit

Permalink
🔀 Merge pull request #49 from cnr-ibba/issue-48
Browse files Browse the repository at this point in the history
🛂 remove restricted access
  • Loading branch information
bunop committed Jun 18, 2024
2 parents 3e60b88 + 2fd2106 commit 983c0b5
Show file tree
Hide file tree
Showing 33 changed files with 217 additions and 648 deletions.
11 changes: 10 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,16 @@
"esbonio.sphinx.confDir": "${workspaceFolder}/flask-data/smarter/docs/source",
"cSpell.words": [
"affymetrix",
"exitfirst",
"iname",
"INITDB",
"jsonify",
"reqparse"
"mongodump",
"mongorestore",
"pytest",
"reqparse",
"showlocals",
"uwsgi",
"uwsgitop"
]
}
19 changes: 3 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,24 +18,12 @@ MONGODB_ROOT_USER=<root user>
MONGODB_ROOT_PASS=<root pass>
MONGODB_SMARTER_USER=<smarter user>
MONGODB_SMARTER_PASS=<smarter pass>
JWT_SECRET_KEY=<secret key>
```

> *TODO*: manage sensitive data using secret in docker-compose, as described
[here](https://docs.docker.com/engine/swarm/secrets/#use-secrets-in-compose) and
[here](https://docs.docker.com/compose/compose-file/#secrets)

### Genereate the JWT secret key

[Here](https://stackoverflow.com/a/23728630/4385116) you can find hints on
how to define a secret key with python:

```python
import string
import secrets
print(''.join(secrets.choice(string.ascii_letters + string.digits) for _ in range(50)))
```

## Setting the proper permissions

Set `mongodb-home` folder permissions with:
Expand All @@ -53,12 +41,11 @@ cd flask-data/
find . -type f -iname "*.py" -exec chmod g-w {} \;
```

## Add a smarter user

Add a smarter user by calling a *flask script*:
## Build and run the application

```bash
docker-compose run --rm uwsgi flask users create smarter
docker-compose build
docker-compose up
```

## Connect to mongodb
Expand Down
14 changes: 0 additions & 14 deletions flask-data/smarter/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,13 @@

from flask import Flask, redirect, url_for
from flask_restful import Api
from flask_bcrypt import Bcrypt
from flask_jwt_extended import JWTManager
from flask.json import JSONEncoder
from flask_cors import CORS
from flasgger import Swagger

from database.db import initialize_db, DB_ALIAS
from resources.errors import errors
from resources.routes import initialize_routes
from commands import usersbp

__version__ = "0.3.0.dev0"

Expand Down Expand Up @@ -72,15 +69,10 @@ def create_app(config={}):
app = Flask(__name__)
CORS(app)
api = Api(app, errors=errors)
Bcrypt(app)
JWTManager(app)

# deal with ObjectId in json responses
app.json_encoder = CustomJSONEncoder

# workaround to make flasgger deal with jwt-token headers
app.config["JWT_AUTH_URL_RULE"] = True

# Swagger stuff
swagger_template = {
"swagger": "2.0",
Expand Down Expand Up @@ -130,18 +122,12 @@ def create_app(config={}):
app.logger.error(f"Setting custom host: {config['host']}")
app.config['MONGODB_SETTINGS']['host'] = config['host']

# https://flask-jwt-extended.readthedocs.io/en/stable/basic_usage/
app.config["JWT_SECRET_KEY"] = os.getenv('JWT_SECRET_KEY')

# connect to database
initialize_db(app)

app.logger.debug("Database initialized")
app.logger.debug(f"Got encoder {app.json_encoder}")

# you MUST register the blueprint
app.register_blueprint(usersbp)

# add resources
initialize_routes(api)

Expand Down
41 changes: 0 additions & 41 deletions flask-data/smarter/commands.py

This file was deleted.

15 changes: 0 additions & 15 deletions flask-data/smarter/database/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@

from enum import Enum

from flask_bcrypt import check_password_hash

from .db import db, DB_ALIAS

# Get an instance of a logger
Expand Down Expand Up @@ -39,19 +37,6 @@ class SmarterDBException(Exception):
pass


class User(db.Document):
username = db.StringField(required=True, unique=True)
password = db.StringField(required=True, min_length=6)

def check_password(self, password):
return check_password_hash(self.password, password)

meta = {
'db_alias': DB_ALIAS,
'collection': 'user'
}


class SmarterInfo(db.Document):
"""A class to track database status informations"""

Expand Down
73 changes: 32 additions & 41 deletions flask-data/smarter/docs/source/accessing.rst
Original file line number Diff line number Diff line change
@@ -1,41 +1,32 @@

Accessing SMARTER-backend
=========================

Authentication
--------------

In the following sections you will find examples on how to interact with the
SMARTER-backend in different ways. Regardless the method your prefer, you are
required to generate a :ref:`JWT Token <JWT Authentication>` before accessing data.
This token need to be added to each **header** request made to any SMARTER-backend
endpoint, with the following format::

Authorization: Bearer <your token>

Please remeber that the token is valid only for 7 days, then you will need to
generate a new JWT token in order to access SMARTER metadata.
The SMARTER-backend is a RESTful API, which means that it's a web service that
provides access to its resources via HTTP requests. The API is designed to be
simple and easy to use, and it's based on the `JSON <https://www.json.org/json-en.html>`_
data format, which is a lightweight data-interchange format that is easy for
humans to read and write and easy for machines to parse and generate.

Query parameters
----------------

The :ref:`API endpoints` described in the :ref:`Introduction` return by default
all the SMARTER objects they managed. However it's possible to filter out the
results returned using ``GET`` parameters (also called URL parameters or
`query strings <https://en.wikipedia.org/wiki/Query_string>`_) which are usually
name-value pairs, separated by an ``=`` sign. For example, by submitting a request
The :ref:`API endpoints` described in the :ref:`Introduction` return by default
all the SMARTER objects they managed. However it's possible to filter out the
results returned using ``GET`` parameters (also called URL parameters or
`query strings <https://en.wikipedia.org/wiki/Query_string>`_) which are usually
name-value pairs, separated by an ``=`` sign. For example, by submitting a request
to::

https://webserver.ibba.cnr.it/smarter-api/breeds

You will get all the Breeds stored in smarter database, but you can filter out
You will get all the Breeds stored in smarter database, but you can filter out
the results by species by passing ``species=Goat`` parameter::

https://webserver.ibba.cnr.it/smarter-api/breeds?species=Goat

Please note that parameters are not part of the API endpoint: The question mark
is used as a separator, and divide the endpoint from the ``GET`` parameter. You
can provide multiple parameters by joining them with the ``&`` character, for
Please note that parameters are not part of the API endpoint: The question mark
is used as a separator, and divide the endpoint from the ``GET`` parameter. You
can provide multiple parameters by joining them with the ``&`` character, for
example::

https://webserver.ibba.cnr.it/smarter-api/breeds?species=Goat&search=land
Expand All @@ -45,19 +36,19 @@ for example, but also *Rangeland*)

.. hint::

The page https://webserver.ibba.cnr.it/smarter-api/docs/ describes every API
endpoints with their own set of parameters, see the proper endpoint
The page https://webserver.ibba.cnr.it/smarter-api/docs/ describes every API
endpoints with their own set of parameters, see the proper endpoint
documentation to have a list of the allowed parameters and what they do.

Pagination
----------

API queries could returned thousands of results, so to improve performance and
lower traffic between client and server, all the API endpoints implements pagination.
This means that each query returns a limited set of results, but it returns also
the total number of objects with informations useful to collect the next batch
of objects. For example, if you analyze the breed API response while search for
all the objects (``https://webserver.ibba.cnr.it/smarter-api/breeds``), you will
API queries could returned thousands of results, so to improve performance and
lower traffic between client and server, all the API endpoints implements pagination.
This means that each query returns a limited set of results, but it returns also
the total number of objects with informations useful to collect the next batch
of objects. For example, if you analyze the breed API response while search for
all the objects (``https://webserver.ibba.cnr.it/smarter-api/breeds``), you will
see a reply like this::

{
Expand All @@ -72,25 +63,25 @@ see a reply like this::
"total": 257
}

Where in the ``items`` array there will be ``size`` Breed objects (default 10,
omitted here to better describe the response); in the ``next`` attribute there
will be the URLs to be used to get the next batch of objects, if you
get the next page, you will get a ``prev`` attribute for the previous page;
The ``total`` stands for the total number of breed objects and the ``page``
stands for the current batch page number. By default, the behaviour is to
Where in the ``items`` array there will be ``size`` Breed objects (default 10,
omitted here to better describe the response); in the ``next`` attribute there
will be the URLs to be used to get the next batch of objects, if you
get the next page, you will get a ``prev`` attribute for the previous page;
The ``total`` stands for the total number of breed objects and the ``page``
stands for the current batch page number. By default, the behaviour is to
display 10 results per page, however you could change this by setting a different
page size with a get parameter, for example ``size=20``.

.. warning::
.. warning::

Please remember that pagination helps to better manage resources, don't
try to retrieve all the results for a single query request: there could be
Please remember that pagination helps to better manage resources, don't
try to retrieve all the results for a single query request: there could be
a size limit or you can have issues in retrieve / process the results

Examples
--------

Here we list some patterns on how to interact with the SMARTER-backend, feel free
Here we list some patterns on how to interact with the SMARTER-backend, feel free
to follow the method you prefer:

.. toctree::
Expand Down
Loading

0 comments on commit 983c0b5

Please sign in to comment.