Git Product home page Git Product logo

ecommerce_api's Introduction

ecommerce API

Setup

Before you start, it's recommended to create a new virtualenv for the application

Linux Ubuntu

mkvirtualenv ecommerce -p /usr/bin/python3

macOS

virtualenv -p python3 ecommerce
source ecommerce/bin/activate

Then, install the required modules with the command

pip3 install -r requirements.txt

Heroku Support

Create a .env file with the following environment variables

PYTHONPATH=.
FLASK_APP=app.py
FLASK_DEBUG=1
ENVIRONMENT=dev

Install Heroku toolbelt.

wget -qO- https://cli-assets.heroku.com/install-ubuntu.sh | sh

In order to launch the server:

heroku local -f Procfile.dev

Demo scripts

These scripts create fake contents in the database for local testing purpose.

init-db.py initialize the database by deleting existing tables and creating new ones. demo-content.py inserts random contents in database tables created by init-db.py.

You must first run init-db.py before launch demo-content.py. Enter in the virtualenv and run scripts by command line:

PYTHONPATH=. python scripts/init-db.py

After initialization of database, run:

PYTHONPATH=. python scripts/demo-content.py

ecommerce_api's People

Contributors

albepao avatar alecappe avatar fv89 avatar gendoikari avatar gvaldambrini avatar iryko avatar lucaarrey avatar ryukaj95 avatar soraph avatar vincenzo10 avatar

Watchers

 avatar  avatar

ecommerce_api's Issues

ItemPictures view

Abbiamo bisogno di due risorse per gestire le immagini:

  • ItemPictures [/items/uuid:uuid/pictures]
    GET -> ritorna la lista di pictures uuid di un item
    POST -> upload di immagine per quell'item

demo-content seed

Al momento non è possibile eseguire questa sequenza di comandi:

PYTHONPATH=. scripts/init-db.py
PYTHONPATH=. python scripts/demo-content.py
PYTHONPATH=. python scripts/demo-content.py

poiché si ottiene sul secondo demo-content:

peewee.IntegrityError: UNIQUE constraint failed: item.uuid

la ragione è che usiamo un seed che è hardcodato nel sorgente. E' necessario modificare il demo-content perché il seed (numero intero) possa essere passato allo script come argomento command line gestito tramite argparse. Il valore passato allo script dovrà andare a rimpiazzare i valori usati attualmente nel sorgente (sia per random che per Faker).

implementare la patch di item

A differenza delle put, le patch accettano elementi parziali, e vanno a modificare solo gli attributi che cambiano, senza distruggere e ricreare l'intero oggetto.

Usare verify_json per gli address

Adesso abbiamo gli Schema di marshmallow, e in classe base models BaseModel abbiamo verify_json (classmethod). Possiamo cominciare a sostituire i vari request parse con la verify_json, partendo appunto da address.
Notando che:

  1. stiamo usando marshmallow per gli schema, schemas.py
  2. stiamo usando jsonschema per la validazione del json, in particolare jsonschema.validate che ritorna una ValidationError se il json non e' conforme allo schema.
  3. possiamo prendere il messaggio di errore dall'eccezione (in un try...except) e ritornare BAD_REQUEST e il messaggio se il json dato dal client non e' valido

Metodo BaseTest.open_with_auth può essere rimosso

def open_with_auth(self, url, method, email, password, data):
        return self.app.open(
            url, method=method, headers={'Authorization': 'Basic ' + base64.b64encode(
                bytes(email + ":" + password, 'ascii')).decode('ascii')}, data=data)

Credo possa essere sostituito con un metodo che generi la stringa per Headers da passare alla chiamata necessaria nel test (che sia self.post, self.get, etc..) invece che complicare il tutto con tutti questi parametri.

Qualcosa del tipo:

def authenticated_headers(self, email, password):
    return {
        'Authorization': 'Basic ' + base64.b64encode(bytes(email + ":" + password, 'ascii')).decode('ascii')
    }

Incoerenza tra i valori di entrata ed uscita per il method post() di AddressesResource

class AddressesResource(Resource):
    def post(self):
        [...]
        parser.add_argument('user_id', type=utils.non_empty_str, required=True)
        [...]

        address = Address.create(
            uuid=uuid.uuid4(),
            user=user,
            [...]
        )

        return address.json(), CREATED

Viene richiesto il parametro user_id ma viene restituito user, questo crea complessità aggiuntiva nella gestione dei test rendendo difficile controllare i dati di invio e di ritorno rapidamente.

aggiungere modello address utenti

E' necessario creare un modello Address che rappresente il concetto di "indirizzo di spedizione". Un utente (modello User) puà avere più address, ma un address ha un solo utente possibile. Un address ha nazione, città, cap, indirizzo, numero di telefono, nome e cognome. E' necessario aggiungere l'address agli script di init-db e demo-content.

Item pictures Table

Gli item possono avere delle picture. Un item puo' avere piu' picture, una picture puo' avere un item solo.
Una picture ha un uuid, una extension e un link a item.

implementare la patch di address

Abbiamo la put, che sostituisce completamente un address con un altro.
Implementiamo anche la patch, che permette di avere sostituzioni parziali.

api json per gli Order

Dovrà essere possibile creare, modificare, cancellare o visualizzare (il singolo elemento o la lista) degli Order. Sarà necessario realizzare anche adeguata suite di test.

Cleanup test item

Ci sono dei test che fanno a mano la Item.create invece di usare il nostro standard self.create_item. Fixiamo.

Implementare la reload

In models la classe base dovrebbe implementare la refresh. Ovvero una funzione che, chiamata su un oggetto peewee, vada a ricaricare i suoi valori presi dal database.
Questo:
item = User.get(User.uuid == item.uuid)
diventa questo:
item = item.reload()

aggiungere viste address

Dovrà essere possibile:

  • creare un nuovo address associato ad un utente (POST /addresses/)
  • modificare un address esistente (PUT /addresses/<id>)
  • ottenere un address esistente (GET /addresses/<id>)
  • eliminare un address esistente (DELETE /addresses/<id>)

Sarà necessario realizzare gli unit test per verificare il corretto comportamento delle viste.

aggiungere la categoria agli item

E' necessario aggiungere un campo category al modello degli Item, e ovviamente anche aggiornare le viste e i test per tenerne conto. Inizialmente la categoria sarà una semplice stringa, in un futuro creeremo un modello e delle viste dedicate.

User state

Aggiungiamo il campo status allo User, che sara' enable per ogni utente standard. Lo status potrebbe pero' essere blocked per gli utenti bloccati, e deleted per gli utenti cancellati.
La delete di User adesso dovrebbe cambiare il campo state a deleted.
Uno user si puo' autenticare solo se e' enable.

README per il demo content

Aggiungiamo un README.md con tutte le informazioni per lanciare il demo content, gli scripts, dove sono cosa fanno etc...
Usiamo il formato markdown di github.

availability per gli item

Ogni item dovrà essere dotato di un campo availability, numero intero che indica la quantità di item a disposizione. Un utente potrà fare ordini solo di item che hanno disponibilità > 0 e ogni
ordine effettuato dovrà modificare in modo opportuno la disponibilità. E' da gestire anche il caso in cui una PUT su un ordine cerchi di aggiungere della quantità per un item che non ne ha, e in quel caso il server dovrà rispondere con un 403 (forbidden)

demo-content

Sarà necessario creare due script (da mettere dentro la directory scripts):

  • il primo chiamato init-db.py dovrà andare ad eliminare il database corrente e ricreare tutte le tabelle;
  • il secondo chiamato demo-content.py dovrà andare a generare alcuni utenti, ordini e item di prova. Usiamo Faker per generare i dati, specificando il seed in modo che i dati generati siano riproducibili.

Entrambi gli script NON richiederanno argomenti a linea di comando.

Supporto Email

  • Account heroku
  • Aggiungere nel .env le config di mailgun e usarle per avere mailgun
  • Creare un modulo che abbia un'api per mandare delle mail
  • Usiamo i template html di flask per il corpo dell'email
  • La funzione send_email deve prendere come parametri un template (ce ne sara' uno di default), e uno kwargs di parametri chiave-valore che saranno poi sostituiti nel template, e i parametri obbligatori di mailgun (titolo?)

Il codice di views/item.py può essere semplificato

Esempio:

try:
    utils.non_empty_str(args['name'], 'name')
except ValueError:
    return None, BAD_REQUEST

Può essere una semplice modifica all'argument:

parser.add_argument('name', type=utils.non_empty_str, required=True)

supporto heroku

Per supportare heroku occorre:

  • avere due file, un Procfile e un Procfile.dev con le righe di comando necessarie ad avviare il server rispettivamente su heroku e in locale
  • un file runtime.txt con specificata la versione di python che stiamo usando
  • un file .env in locale, non committato, con le variabili di ambiente scritta in formato VARIABILE=valore

I test di Address sono incorretti

Esempio:

    def test_get__address_found(self):
        data_user = User.get()
        address_id_created = uuid.uuid4()
        Address.create(
            [...]
            )

        resp = self.app.get('/addresses/{}'.format(address_id_created))
        query = Address.get()
        assert resp.status_code == OK
        assert query.json() == json.loads(resp.data.decode())

In questo caso viene ignorato l'oggetto creato e viene confrontato il dato recuperato dal database (che c'è già, creato poco prima) con la risposta del server

aggiungere i preferiti

Sarà necessario aggiungere il concetto dei favourites, che vuol dire:

  • aggiungere un modello Favorites composto da una primary key che è lo User e un altra che è l'Item
  • aggiungere un endpoint /favorites/ che supporti i verbi GET per elencare tutti gli item preferiti di un utente (utente che verrà ricavato dall'utente attualmente autenticato) e POST per crearne uno nuovo il cui id è specificato nel json della richiesta
  • aggiungere un endpoint /favorites/<item_id> che supporterà il verbo DELETE per eliminare il preferito
  • il modello dell'utente dovrà essere dotato di un metodo add_favorite(item) e remove_favorite(item) che vadano rispettivamente a creare o rimuovere un preferito

api json per gli Item

Dovrà essere possibile creare un nuovo Item, modificarlo, cancellarlo o visualizzarlo (il singolo Item o l'insieme di Item). Sarà necessario realizzare anche adeguata suite di test.

aggiungere script per creare utenti superuser

E' necessario aggiungere un flag admin boolean che discrimini utenti normali da quelli admin. Gli utenti creati attraverso la relativa API (in sviluppo) saranno tutti utenti normali, e gli utenti admin dovranno essere creati "manualmente" aggiungendo uno script nella directory scripts chiamato create_superuser.py e che, usando Click (http://click.pocoo.org/5/), richieda email e password del nuovo utente.

api json per gli User

Deve essere possibile creare un nuovo utente, modificarlo o cancellarlo. Sarà necessario realizzare anche adeguata suite di test.

Reset della password

  • Nuova tabella Reset
    code -> uuid primary key
    user -> foreign key user
    expiration -> date
    enable -> boolean
  • POST /users/reset <- {"email": "...."}
    Il codice di questa post e' sempre okay no content.
    Questa post crea nella tabella Reset un record associato a questo utente, con un codice generato casualmente, una expiration date di un'ora, e lo user.
    Se esistevano altri code gia' emessi per questo utente, metterli tutti a enable == false. Solo un codice puo' essere valido alla volta.
  • POST /resets <- {"code": "....", "password": "..."}
    Prende l'utente associato a quel code, che deve essere valido, e gli imposta la password. Il campo enable della Reset deve essere false.

items refactoring

Uniformare il nome della viste degli items a quanto già presente per gli utenti, chiamandole rispettivamente:

 ItemsResource
 ItemResource

Rimuovere anche la funzione string_not_empty e utilizzare al suo posto la funzione non_empty_str che adesso è definita in views/user.py e che andrà spostata in un file utils.py

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.