Skip to content

Ajout d'API dans le projet angardia-ai

Cyrille a besoin d'API pour créer des éléments dans la base de données sans devoir créer une UI pour le moment.

Instruction de Cyrille

API 1 : créer un un Case (récupéré comme ça)
$case = \App\Models\Caze::where('name', '#blockout2024')->firstOrFail(); 
API 2 : créer et lancer un Crawl
$crawl = \App\Models\Crawl::create([
            'case_id' => $case->id,
            'text_format' => \App\Enums\TextFormatEnum::MARKDOWN,
            'vpn_exit_country' => \App\Enums\CountryEnum::US,
            'blacklisted_urls' => [
                'facebook.com/',
                'instagram.com/',
                'reddit.com/u/',
                'youtube.com/',
                'tiktok.com/channel/',
            ],
            'queries_must_have_tokens' => [
                ['boycott', 'oreal'],
                ['genocide', 'oreal'],
                ['blockout2024', 'oreal'],
                ['blockout', 'oreal'],
                ['boycott', 'oréal'],
                ['genocide', 'oréal'],
                ['blockout2024', 'oréal'],
                ['blockout', 'oréal'],
            ],
            'texts_must_have_tokens' => [
                ['blockout', '2024'],
            ],
            'root_query' => 'blockout2024 l\'oréal site:tiktok.com',
            'depth' => 0,
            'max_depth' => 2,
            'max_iterations' => 100,
            'search_engine' => \App\Enums\SearchEngineEnum::GOOGLE,
            'page_start' => 1,
            'page_length' => 100,
        ]);

Crawler::search($crawl);    
API 3 : créer un EntityGroup à partir d'un tableau de strings
$egeries = [
        'Kendall Jenner' => [metaphone('Kendall Jenner'), metaphone('Kendall'), metaphone('Jenner')],
        'Marie Bochet' => [metaphone('Marie Bochet'), metaphone('Marie'), metaphone('Bochet')],
        'Cindy Bruna' => [metaphone('Cindy Bruna'), metaphone('Cindy'), metaphone('Bruna')],
        'Cara Delevigne' => [metaphone('Cara Delevigne'), metaphone('Cara'), metaphone('Delevigne')],
        'Viola Davis' => [metaphone('Viola Davis'), metaphone('Viola'), metaphone('Davis')],
        'Romain Ntamack' => [metaphone('Romain Ntamack'), metaphone('Romain'), metaphone('Ntamack')],
        'Jane Fonda' => [metaphone('Jane Fonda'), metaphone('Jane'), metaphone('Fonda')],
        'Andie MacDowell' => [metaphone('Andie MacDowell'), metaphone('Andie'), metaphone('MacDowell')],
        'Elle Fanning' => [metaphone('Elle Fanning'), metaphone('Elle'), metaphone('Fanning')],
        'Alia Bhatt' => [metaphone('Alia Bhatt'), metaphone('Alia'), metaphone('Bhatt')],
        'Luma Grothe' => [metaphone('Luma Grothe'), metaphone('Luma'), metaphone('Grothe')],
        'Yseult' => [metaphone('Yseult')],
        'Aishwarya Rai' => [metaphone('Aishwarya Rai'), metaphone('Aishwarya'), metaphone('Rai')],
        'Aja Naomi King' => [metaphone('Aja Naomi King'), metaphone('Aja'), metaphone('Naomi'), metaphone('King')],
        'Eva Longoria' => [metaphone('Eva Longoria'), metaphone('Eva'), metaphone('Longoria')],
        'Helen Mirren' => [metaphone('Helen Mirren'), metaphone('Helen'), metaphone('Mirren')],
        'Gillian Anderson' => [metaphone('Gillian Anderson'), metaphone('Gillian'), metaphone('Anderson')],
        'Liya Kebede' => [metaphone('Liya Kebede'), metaphone('Liya'), metaphone('Kebede')],
        'Renée Rapp' => [metaphone('Renée Rapp'), metaphone('Renée'), metaphone('Rapp')]
    ];
    foreach ($egeries as $egerie => $metaphones) {
        foreach ($metaphones as $metaphone) {
            \App\Models\EntityGroup::create([
                'case_id' => 1,
                'type' => 'Egéries',
                'name' => $egerie,
                'entity_type' => \App\Enums\EntityTypeEnum::PERSON,
                'entity_metaphone' => $metaphone,
            ]);
        }
    }

Mise en oeuvre

Je me rends compte qu'il n'y a pas de fichier routes/api.php. Avec Laravel 11, il faut faire cette commande pour le mettre en place :

php artisan install:api

Cela utilise Laravel Sanctum pour générer les tokens.

J'ai tourné en rond 2h sans trouver comment faire pour avoir un token que je puisse passer à l'API ou pour faire une requête GET à l'API depuis mon navigateur pour être authentifier grâce au cookie...

Je vais donc faire des routes non protégées mais que je protègerai grâce à une clé mise dans mon .env

Case - 3 routes basiques

  • POST /case = crée un case
  • GET /case/{caze} = renvoie le case correspondant
  • DELETE /case/{caze} = supprime le case correspondant
Exemple de JSON pour la création
{ "name":"example", "description":"this is an example description" } 

Crawl

Les mêmes 3 routes basiques que pour case :

  • POST /crawl = crée un crawl
  • GET /crawl/{crawl} = renvoie le crawl correspondant
  • DELETE /crawl/{crawl} = supprime le crawl correspondant
Exemple de JSON pour la création
{
    "case_id": 2,
    "text_format": "markdown",
    "vpn_exit_country": "US",
    "blacklisted_urls": ["facebook.com/", "instagram.com/", "reddit.com/u/", "youtube.com/", "tiktok.com/channel/"],
    "queries_must_have_tokens": [
        ["boycott", "oreal"],
        ["genocide", "oreal"],
        ["blockout2024", "oreal"],
        ["blockout", "oreal"],
        ["boycott", "oréal"],
        ["genocide", "oréal"],
        ["blockout2024", "oréal"],
        ["blockout", "oréal"]
    ],
    "texts_must_have_tokens": [
        ["blockout", "2024"]
    ],
    "root_query": "blockout2024 l'oréal site:tiktok.com",
    "depth": 0,
    "max_depth": 2,
    "max_iterations": 100,
    "search_engine": "google",
    "page_start": 1,
    "page_length": 100
}

Et une route permettant de lancer un Crawl :

  • POST /crawl/{crawl}/launch = lance le crawl correspondant

EntityGroup

Le but de cette API est de pouvoir créer ou mettre à jour des EntityGroup à partir d'une liste, une mise à jour par lot.

  • POST /entity-group/batch = Create or update a batch of EntityGroup
Exemple de JSON pour la création
{
    "case_id": 2,
    "type": "Egéries",
    "entity_type": "person",
    "entity_groups": [
        { "name": "Kendall Jenner", "metaphones": ["Kendall Jenner", "Kendall", "Jenner"] },
        { "name": "Marie Bochet", "metaphones": ["Marie Bochet", "Marie", "Bochet"] },
        { "name": "Cindy Bruna", "metaphones": ["Cindy Bruna", "Cindy", "Bruna"] },
        { "name": "Cara Delevigne", "metaphones": ["Cara Delevigne", "Cara", "Delevigne"] },
        { "name": "Viola Davis", "metaphones": ["Viola Davis", "Viola", "Davis"] },
        { "name": "Romain Ntamack", "metaphones": ["Romain Ntamack", "Romain", "Ntamack"] },
        { "name": "Jane Fonda", "metaphones": ["Jane Fonda", "Jane", "Fonda"] },
        { "name": "Andie MacDowell", "metaphones": ["Andie MacDowell", "Andie", "MacDowell"] },
        { "name": "Elle Fanning", "metaphones": ["Elle Fanning", "Elle", "Fanning"] },
        { "name": "Alia Bhatt", "metaphones": ["Alia Bhatt", "Alia", "Bhatt"] },
        { "name": "Luma Grothe", "metaphones": ["Luma Grothe", "Luma", "Grothe"] },
        { "name": "Yseult", "metaphones": ["Yseult"] },
        { "name": "Aishwarya Rai", "metaphones": ["Aishwarya Rai", "Aishwarya", "Rai"] },
        { "name": "Aja Naomi King", "metaphones": ["Aja Naomi King", "Aja", "Naomi", "King"] },
        { "name": "Eva Longoria", "metaphones": ["Eva Longoria", "Eva", "Longoria"] },
        { "name": "Helen Mirren", "metaphones": ["Helen Mirren", "Helen", "Mirren"] },
        { "name": "Gillian Anderson", "metaphones": ["Gillian Anderson", "Gillian", "Anderson"] },
        { "name": "Liya Kebede", "metaphones": ["Liya Kebede", "Liya", "Kebede"] },
        { "name": "Renée Rapp", "metaphones": ["Renée Rapp", "Renée", "Rapp"] }
    ]
}

L'API supprime les EntityGroup en trop et renvoie le nombre de mises à jour (EntityGroup déjà existant et conservé), de créations et de suppressions.