Skip to content
Permalink
Browse files
Create gh-pages branch via GitHub
  • Loading branch information
soperd committed Nov 26, 2018
1 parent 4d22124 commit 1ee6ad05ab3f19d99ca68e28473568e594bc9332
Show file tree
Hide file tree
Showing 3 changed files with 286 additions and 334 deletions.
@@ -1,41 +1,23 @@
<!doctype html>
<html>
<!DOCTYPE html>
<html lang="en-us">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="chrome=1">
<meta charset="UTF-8">
<title>chatbot by soperd</title>
<link rel="stylesheet" href="stylesheets/styles.css">
<link rel="stylesheet" href="stylesheets/github-dark.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="javascripts/respond.js"></script>
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<!--[if lt IE 8]>
<link rel="stylesheet" href="stylesheets/ie.css">
<![endif]-->
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">

<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" type="text/css" href="stylesheets/normalize.css" media="screen">
<link href='https://fonts.googleapis.com/css?family=Open+Sans:400,700' rel='stylesheet' type='text/css'>
<link rel="stylesheet" type="text/css" href="stylesheets/stylesheet.css" media="screen">
<link rel="stylesheet" type="text/css" href="stylesheets/github-light.css" media="screen">
</head>
<body>
<div id="header">
<nav>
<li class="fork"><a href="https://github.coventry.ac.uk/soperd/chatbot-docs">View On GitHub</a></li>
</nav>
</div><!-- end header -->

<div class="wrapper">

<section>
<div id="title">
<h1>chatbot</h1>
<p>Year 1 Project</p>
<hr>
<span class="credits left">Project maintained by <a href="https://github.coventry.ac.uk/soperd">soperd</a></span>
<span class="credits right">Hosted on GitHub Pages &mdash; Theme by <a href="https://twitter.com/michigangraham">mattgraham</a></span>
</div>
<section class="page-header">
<h1 class="project-name">chatbot</h1>
<h2 class="project-tagline">Year 1 Project</h2>
<a href="https://github.coventry.ac.uk/soperd/chatbot-docs" class="btn">View on GitHub</a>
</section>

<h3>
<section class="main-content">
<h3>
<a id="introduction" class="anchor" href="#introduction" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Introduction</h3>
<p>This is a reflective piece on my Year 1 group project. Please view the code <a href="https://github.coventry.ac.uk/soperd/chatbot">here</a>.</p>
<p>The project is a chatbot written in Python 3 primarily for use with Discord. Current features include:</p>
@@ -78,15 +60,20 @@
<span class="pl-s"><span class="pl-pds">"</span>port<span class="pl-pds">"</span></span>: <span class="pl-c1">6379</span>
}
}</pre></div>
<p>This details that the Discord bot has a token and a set of services it can use. For this example, it can use the weather and location services. When we run the bot using the <code>run_discord.py</code> script, this passes the <code>discord</code> configuration to the <code>DiscordBot</code> class constructor, which in turn calls <code>ChatBot</code>'s constructor. If the optional parameter <code>services</code> :p is <code>None</code> then <code>ChatBot</code>'s constructor then will find the services listed in <code>config.json</code> from the <code>global_services</code> and store them in the <code>services</code> class member. This was my attempt to "inject" services into the bot automatically.</p>
<p>This details that the Discord bot has a token and a set of services it can use. For this example, it can use the weather and location services. When we run the bot using the <code>run_discord.py</code> script, this passes the <code>discord</code> configuration to the <code>DiscordBot</code> class constructor, which in turn calls <code>ChatBot</code>'s constructor. If the optional parameter <code>services</code> is <code>None</code> then <code>ChatBot</code>'s constructor then will find the services listed in <code>config.json</code> from the <code>global_services</code> and store them in the <code>services</code> class member. This was my attempt to "inject" services into the bot automatically.</p>
<p><code>DiscordBot</code> is currently the only functioning bot. It uses the Discord.py library which makes for easy integration with Discord's API.</p>
<h3>
<a id="reflection" class="anchor" href="#reflection" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Reflection</h3>
<p>I think my design worked well for the most part. If we decided we wanted to integrate the app into WhatsApp or Messenger, I feel that my design would aid in porting our features over to the new bot. This design also allows for multiple bots with similar features on the same platform, which I am happy with. I do, however, believe that in some areas my code is poorly implemented, such as :p the <code>global_services</code> dictionary. This seems like a bit of a hack, and it wasn't really necessary to achieve my goal. That being said, this is the first time I've used a custom decorator in Python and I can see its potential elsewhere.</p>
</section>
<p>I think my design worked well for the most part. If we decided we wanted to integrate the app into WhatsApp or Messenger, I feel that my design would aid in porting our features over to the new bot. This design also allows for multiple bots with similar features on the same platform, which I am happy with. I do, however, believe that in some areas my code is poorly implemented, such as the <code>global_services</code> dictionary. This seems like a bit of a hack, and it wasn't really necessary to achieve my goal. That being said, this is the first time I've used a custom decorator in Python and I can see its potential elsewhere.</p>

<footer class="site-footer">
<span class="site-footer-owner"><a href="https://github.coventry.ac.uk/soperd/chatbot-docs">chatbot</a> is maintained by <a href="https://github.coventry.ac.uk/soperd">soperd</a>.</span>

<span class="site-footer-credits">This page was generated by <a href="https://pages.github.com">GitHub Pages</a> using the <a href="https://github.com/jasonlong/cayman-theme">Cayman theme</a> by <a href="https://twitter.com/jasonlong">Jason Long</a>.</span>
</footer>

</section>

</div>
<!--[if !IE]><script>fixScale(document);</script><![endif]-->


</body>
</html>
@@ -1,6 +1,6 @@
{
"name": "chatbot",
"tagline": "Year 1 Project",
"body": "### Introduction\r\nThis is a reflective piece on my Year 1 group project. Please view the code [here](https://github.coventry.ac.uk/soperd/chatbot).\r\n\r\nThe project is a chatbot written in Python 3 primarily for use with Discord. Current features include:\r\n- Some natural language understanding with [RasaNLU](https://rasa.com/).\r\n- Weather forecast integration with [DarkSky](https://darksky.net/).\r\n- Location services with [Nominantim by OpenStreetMaps](https://nominatim.openstreetmap.org/).\r\n- Datastore integration with [Redis](https://redis.io/).\r\n\r\n\r\n### Design\r\nAs the most experienced member of my team, I set down the foundation for the bot's design and structure. At the time, we were unsure what platform which platforms we wanted to target, so I set out by separating the platform-specific implementations from the platform-neutral services.\r\n\r\nI did this by putting all code that provided some kind of generic services into the `handlers` folder of the project. Here you can find a file called `services.py` which contains a class called `Service` that acts as a configurable base class. All other services in `handlers` inherits this `Service` class and implements its own functionality. For example, the `WeatherService` class in `weather.py` contains methods like `get_weather_at` that takes a given longitude and latitude and queries DarkSky's forecast API. \r\n\r\nThe services can then be registered using the `register_service` decorator that can be found in `services.py`. The decorator takes a name as a parameter, then resolves the config provided to that service with the same name detailed in `config.json`, and stores it in the dictionary `global_services`.\r\n\r\nFor all the platform specific implementations, I put the code in the `wrappers` folder. This contains a file called `bot.py` which has a class `ChatBot`. This acts as an interface that defines common behaviours for every bot with methods such as `start` and `stop`, since the reasoning behind it was that every bot must at least start and be able to be stopped. At the moment, the only implemented platform is Discord, the code for which can be seen in `discord.py`. Here we can see the bot inherits `ChatBot`, implements the `start` method and defines its own. `ChatBot` also declares three class members:\r\n- `services`: A dictionary containing instances of services for the bot to use.\r\n- `datastore`: A Redis client object for the bot to access the datastore.\r\n- `config`: A `ConfigDict` object that acts as a representation of the bot's config in `config.json` (see below).\r\n\r\nBoth services and wrappers are configurable via the `config.json` file, which looks something like this:\r\n\r\n```json\r\n{\r\n \"discord\": {\r\n \"token\": \"<DISCORD TOKEN HERE>\",\r\n \"services\": [\r\n \"weather\",\r\n \"location\"\r\n ]\r\n },\r\n \"services\": {\r\n \"weather\": {\r\n \"token\": \"<DARKSKY TOKEN HERE>\"\r\n }\r\n },\r\n \"redis\": {\r\n \"host\": \"localhost\",\r\n \"port\": 6379\r\n }\r\n}\r\n```\r\n\r\nThis details that the Discord bot has a token and a set of services it can use. For this example, it can use the weather and location services. When we run the bot using the `run_discord.py` script, this passes the `discord` configuration to the `DiscordBot` class constructor, which in turn calls `ChatBot`'s constructor. If the optional parameter `services` :p is `None` then `ChatBot`'s constructor then will find the services listed in `config.json` from the `global_services` and store them in the `services` class member. This was my attempt to \"inject\" services into the bot automatically.\r\n\r\n`DiscordBot` is currently the only functioning bot. It uses the Discord.py library which makes for easy integration with Discord's API.\r\n\r\n### Reflection\r\nI think my design worked well for the most part. If we decided we wanted to integrate the app into WhatsApp or Messenger, I feel that my design would aid in porting our features over to the new bot. This design also allows for multiple bots with similar features on the same platform, which I am happy with. I do, however, believe that in some areas my code is poorly implemented, such as :p the `global_services` dictionary. This seems like a bit of a hack, and it wasn't really necessary to achieve my goal. That being said, this is the first time I've used a custom decorator in Python and I can see its potential elsewhere.",
"body": "### Introduction\r\nThis is a reflective piece on my Year 1 group project. Please view the code [here](https://github.coventry.ac.uk/soperd/chatbot).\r\n\r\nThe project is a chatbot written in Python 3 primarily for use with Discord. Current features include:\r\n- Some natural language understanding with [RasaNLU](https://rasa.com/).\r\n- Weather forecast integration with [DarkSky](https://darksky.net/).\r\n- Location services with [Nominantim by OpenStreetMaps](https://nominatim.openstreetmap.org/).\r\n- Datastore integration with [Redis](https://redis.io/).\r\n\r\n\r\n### Design\r\nAs the most experienced member of my team, I set down the foundation for the bot's design and structure. At the time, we were unsure what platform which platforms we wanted to target, so I set out by separating the platform-specific implementations from the platform-neutral services.\r\n\r\nI did this by putting all code that provided some kind of generic services into the `handlers` folder of the project. Here you can find a file called `services.py` which contains a class called `Service` that acts as a configurable base class. All other services in `handlers` inherits this `Service` class and implements its own functionality. For example, the `WeatherService` class in `weather.py` contains methods like `get_weather_at` that takes a given longitude and latitude and queries DarkSky's forecast API. \r\n\r\nThe services can then be registered using the `register_service` decorator that can be found in `services.py`. The decorator takes a name as a parameter, then resolves the config provided to that service with the same name detailed in `config.json`, and stores it in the dictionary `global_services`.\r\n\r\nFor all the platform specific implementations, I put the code in the `wrappers` folder. This contains a file called `bot.py` which has a class `ChatBot`. This acts as an interface that defines common behaviours for every bot with methods such as `start` and `stop`, since the reasoning behind it was that every bot must at least start and be able to be stopped. At the moment, the only implemented platform is Discord, the code for which can be seen in `discord.py`. Here we can see the bot inherits `ChatBot`, implements the `start` method and defines its own. `ChatBot` also declares three class members:\r\n- `services`: A dictionary containing instances of services for the bot to use.\r\n- `datastore`: A Redis client object for the bot to access the datastore.\r\n- `config`: A `ConfigDict` object that acts as a representation of the bot's config in `config.json` (see below).\r\n\r\nBoth services and wrappers are configurable via the `config.json` file, which looks something like this:\r\n\r\n```json\r\n{\r\n \"discord\": {\r\n \"token\": \"<DISCORD TOKEN HERE>\",\r\n \"services\": [\r\n \"weather\",\r\n \"location\"\r\n ]\r\n },\r\n \"services\": {\r\n \"weather\": {\r\n \"token\": \"<DARKSKY TOKEN HERE>\"\r\n }\r\n },\r\n \"redis\": {\r\n \"host\": \"localhost\",\r\n \"port\": 6379\r\n }\r\n}\r\n```\r\n\r\nThis details that the Discord bot has a token and a set of services it can use. For this example, it can use the weather and location services. When we run the bot using the `run_discord.py` script, this passes the `discord` configuration to the `DiscordBot` class constructor, which in turn calls `ChatBot`'s constructor. If the optional parameter `services` is `None` then `ChatBot`'s constructor then will find the services listed in `config.json` from the `global_services` and store them in the `services` class member. This was my attempt to \"inject\" services into the bot automatically.\r\n\r\n`DiscordBot` is currently the only functioning bot. It uses the Discord.py library which makes for easy integration with Discord's API.\r\n\r\n### Reflection\r\nI think my design worked well for the most part. If we decided we wanted to integrate the app into WhatsApp or Messenger, I feel that my design would aid in porting our features over to the new bot. This design also allows for multiple bots with similar features on the same platform, which I am happy with. I do, however, believe that in some areas my code is poorly implemented, such as the `global_services` dictionary. This seems like a bit of a hack, and it wasn't really necessary to achieve my goal. That being said, this is the first time I've used a custom decorator in Python and I can see its potential elsewhere.",
"note": "Don't delete this file! It's used internally to help with page regeneration."
}

0 comments on commit 1ee6ad0

Please sign in to comment.