# Python SDK Tutorial -- News Application

## Overview

### How to Setup and Download Neurelo’s SDKs

In this tutorial, we'll dive into utilizing the **Neurelo Python SDK** to construct a news application from scratch.

To make things interesting, we are building a text-only news app, omitting photos or videos. This emphasizes clarity, conciseness, rapid loading, and accessibility, particularly for individuals with disabilities.

Our approach to building this news application involves envisioning a scenario where a cron job runs every few hours, triggering the execution of a Python script. This script is designed to scrape multiple RSS feeds for content, subsequently updating the application's database with fresh content while removing older news items. Additionally, when a user requests a specific news item, the application fetches the relevant content directly from the database.

At the heart of our news application lies Neurelo, playing a crucial role in facilitating interactions with our database through Neurelo’s Python SDKs.

Before delving into the SDKs and the application's construction, let's lay the groundwork by building a data source and strategizing a schema for our application. We will be using Postgres for this application.

To kick things off, let's create a **New Project** on Neurelo. Click on the **New** icon and input the project details.

<figure><img src="https://3406482452-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FvzFLT4zSSU6J1uzbt5OF%2Fuploads%2FxOKbLSiUve2IP6sY26w3%2FUntitled.png?alt=media" alt="" width="375"><figcaption></figcaption></figure>

Once the information is entered, click on **Introspect** to provide the connection details for inspecting your data source. You can bring your own database (as long as it is accessible to the internet!), or, for evaluation purposes, you can also create a Neurelo provisioned data source by selecting **Empty Project** on the **How would you like to start?** page and then navigating to the **Data Sources** tab.

With an empty data source in place, let's strategize on a schema. At its core, our application requires only a few fields, such as news title, category, summary, and hyperlink. Using this, we can create a schema as follows:

```json
{
  "objects": {
    "News": {
      "properties": {
        "id": {
          "type": "integer",
          "default": {
            "function": "autoincrement"
          },
          "identifier": true
        },
        "category": {
          "type": "string"
        },
        "link": {
          "type": "string"
        },
        "published": {
          "type": "string"
        },
        "summary": {
          "type": "string"
        },
        "title": {
          "type": "string"
        }
      }
    }
  }
}
```

For more information on Neurelo’s Schema Language, refer to our [Neurelo Schema Language (NSL)](https://docs.neurelo.com/neurelo-schema-language-nsl) page.

Let's commit this schema in the **Definitions** tab as outlined below:

<figure><img src="https://3406482452-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FvzFLT4zSSU6J1uzbt5OF%2Fuploads%2FWSIa3ueGOj6aUWiYaamS%2FUntitled%201.png?alt=media" alt=""><figcaption></figcaption></figure>

Next, we will create an environment. Think of a Neurelo environment as a runtime setup where you can interact and run APIs. To create an environment, go to the **Environments** tab and click on the **New** button. Provide the necessary details, such as the desired commit for the environment, the environment region, and the associated data source.

<figure><img src="https://3406482452-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FvzFLT4zSSU6J1uzbt5OF%2Fuploads%2F0q1UjekCE4Qxpm5a6zO2%2FUntitled%202.png?alt=media" alt=""><figcaption></figcaption></figure>

Once the environment is created, applying a migration to our data source is a straightforward process. Head to the **Migrations** tab and validate the migrations that Neurelo has automatically generated for the schema and apply those migrations through Neurelo (if enabled), or download the migrations and apply them to the database using the workflows you may be using.&#x20;

<figure><img src="https://3406482452-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FvzFLT4zSSU6J1uzbt5OF%2Fuploads%2F4AEUUnKWf8sU1N75VlGh%2FUntitled%203.png?alt=media" alt=""><figcaption></figcaption></figure>

And there you have it! With the data source now synchronized with our schema, you can download Neurelo’s Python SDKs by going to the **APIs** tab and selecting the Python SDKs from the **download** menu.

<figure><img src="https://3406482452-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FvzFLT4zSSU6J1uzbt5OF%2Fuploads%2Fd9tO9uVbWXDQ69SjylMn%2FUntitled%204.png?alt=media" alt=""><figcaption></figcaption></figure>

## Building an application with Python SDKs

To learn how to install the Python SDKs, follow the steps outlined in the [Python SDK](https://docs.neurelo.com/sdks/python-sdk) page.

### Environment Configuration

Moving forward, let's create a `News` class and set up two methods to retrieve the environment configuration. This involves utilizing the `Configuration` and `ApiClient` instances as illustrated below:

```python
from dotenv import load_dotenv
import os

from neurelo.configuration import Configuration
from neurelo.api_client import ApiClient

class News:
    def __init__(self) -> None:
        host, key = self.env()
        self.api_client = self.conf(host, key)

    def env(self):
        load_dotenv()
        return (os.getenv("NEURELO_API_HOST") or "", 
                os.getenv("NEURELO_API_KEY") or "")

    def conf(self, host, key):
        configuration = Configuration(host, api_key={"ApiKey": key})
        return ApiClient(configuration=configuration)
```

Later on, you'll notice that each individual schema model API can leverage the `self.api_client`. This API client plays a role in facilitating client-server communication.

To obtain the `NEURELO_API_HOST`, simply copy the host name mentioned in the **Environments** tab.

<figure><img src="https://3406482452-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FvzFLT4zSSU6J1uzbt5OF%2Fuploads%2FMGXtISyWLxCagMWsNy6e%2FUntitled%205.png?alt=media" alt=""><figcaption></figcaption></figure>

Additionally, you can generate a `NEURELO_API_KEY` by creating a new **API Key** from the **API Keys** tab.

<figure><img src="https://3406482452-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FvzFLT4zSSU6J1uzbt5OF%2Fuploads%2FzA5dvIZzSGF71J17qrQy%2FUntitled%206.png?alt=media" alt=""><figcaption></figcaption></figure>

<figure><img src="https://3406482452-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FvzFLT4zSSU6J1uzbt5OF%2Fuploads%2FYnNBLr2mJi7lkTyET8Ub%2FUntitled%207.png?alt=media" alt=""><figcaption></figcaption></figure>

Subsequently, you can export these values using a command similar to the following in your terminal:

```bash
$ export NEURELO_API_KEY="<YOUR-API-KEY>"
$ export NEURELO_API_HOST="<HOST-NAME>"
```

### API Usage

Now, let's expand the functionality of the `News` class to store recent news articles and fetch them, all using our Python SDKs. For instance,

```python
from dotenv import load_dotenv
import os

from neurelo.configuration import Configuration
from neurelo.api_client import ApiClient
from neurelo.api.news_api import NewsApi
from parse_news import Parse

class News:
    def __init__(self) -> None:
        host, key = self.env()
        self.api_client = self.conf(host, key)

    def env(self):
        load_dotenv()
        return (os.getenv("NEURELO_API_HOST") or "", 
                os.getenv("NEURELO_API_KEY") or "")

    def conf(self, host, key):
        configuration = Configuration(host, api_key={"ApiKey": key})
        return ApiClient(configuration=configuration)

    def fetch(self):
        news_api = NewsApi(self.api_client)
        news_item = news_api.find_news()
        return news_item

    def store(self):
        parse = Parse()
        news = parse.parse()
        articles = list(news.values())

        news_api = NewsApi(self.api_client)
        response = news_api.create_many_news(articles)
        return response

    def delete(self):
        news_api = NewsApi(self.api_client)
        deleted = news_api.delete_news()
        return deleted
```

All parameters for every operation come equipped with type hints, making it straightforward to discern the required model or determine if a raw value suffices.

And there you have it! Use the `News` class seamlessly with a web framework like Django or Flask to build your web application.

If you're curious about how the `Parse` class handles the fetching of news items from RSS feeds, take a look at the source code here:

[News Application using Neurelo’s Python SDKs](https://docs.neurelo.com/sdks/python-sdk/python-sdk-tutorial-news-application/news-application-using-neurelos-python-sdks)
