rosscado / raceready Goto Github PK
View Code? Open in Web Editor NEWCreated for toolchain: https://console.bluemix.net/devops/toolchains/0fc11092-0119-4ab8-a5f0-6cbf19d20e03?env_id=ibm%3Ayp%3Aeu-gb
Created for toolchain: https://console.bluemix.net/devops/toolchains/0fc11092-0119-4ab8-a5f0-6cbf19d20e03?env_id=ibm%3Ayp%3Aeu-gb
Example:
title: Laragh Classic
date: "2018-09-01"
event_type: road race
club:
title: St. Tiernans Cycling Club
url: http://www.sttiernanscc.com/
social_media:
handle: "@StTiernansCC"
social_media:
hashtag: "#LaraghClassic"
Add a club
resource to the server-side API.
In the near-term an event
can have an organising_club
relationship with a club
.
In the long-term an athlete
user may have a member_of
relationship with a club
.
Rename Event type
field to event_type
.
This will allow us to reserve the fieldname type
for resource/object/document type, which might be useful in cloudant persistence later.
E.g.
id : uuid
title: My Race
type: event
event_type: road race
Represent the list of stages that compose a race or event.
One-day races are single-stage events.
Publish a REST API that clients can use to retrieve information about an event.
GET /api/event/$id
Format: JSON
{
"id": "cloudant_document_id",
"type": "race",
"race": {
"name": "Clontarf GP",
"discipline": "road",
"stages": [
{
"date": "yyyy/mm/dd",
"start_time": "hh:mm",
"route": {
"distance_km": "100",
"elevation_m": "900"
},
"start_address": "Hill of Howth"
}
],
"organised_by": {
"club": "Clontarf CC",
"primary_contact": "[email protected]"
},
"governing_body": "Cycling Ireland"
}
}
With the Leinster Championships and other races having been cancelled at short notice lately, implement a way to capture the status of a race and any status change notices.
Add an event URL
field to Event resources.
The event URL field will hold a URL that is the primary web address promoting the event, e.g. that hosted by the organising club. This is the URL which athletes are most likely to visit first when looking for further information about an event.
Other event-related URLs of lesser significance may be supported later in separate fields, e.g. cycling_ireland_url
, facebook_url
, etc.
How should the API model represent referenced entities, especially entities that are shared?
For example, a single Circuit
entity may be referenced by many Event
entities. Should the Event
nest the Circuit
as a circuit: {CIRCUIT}
field, point to the external object's primary key circuit_id: {circuit_uuid}
, or point to the object's URI circuit: {circuit_url}
?
fields.Nested
fields.String
fields.Url
Some consider the purest RESTful representation to require addressing resources by hyperlinks to their URIs. By responding with hyperlinks instead of primary keys the server doesn't require the client to have any implicit knowledge about how to use/lookup the primary keys.
Flask RestPlus represents such fields as fields.Url
. Marshmallow represents them as HyperlinkRelated
. Python Eve generates a HATEOAS links
field by default, and returns primary keys unless directed to embed.
According to strict hypermedia representational principles like HATEOAS relationships between resources should be represented as url-addressable links
.
title: Lucan GP
id: {id}
links:
self:
href: /events/{id}
rel: self
organising_club:
- href: /clubs/lrcc
rel: club
races:
- href: /stages/{headline_race_id}
rel: race
- href: /stages/{a4_race_id}
rel: race
The hypermedia principle theoretically supports programmatic navigation by clients by providing them with the complete set of permissible operations in every REST API response. E.g. GET /event/{id}
is responded to with:
links.{relationship}.href
) and actions (HTTP methods)The hypermedia principle extends from the web paradigm where servers have little control over clients; They know little more than that their clients are web browsers that may navigate across the network of resources linked to in the server's responses.
In most practical applications, and certainly in this project's case, there is much more control over the client(s) and its requirements. For us there will be one client initially (in support of a web application with possible mobile application clients added later), a JavaScript library rendering application resources in a web UI.
A compromise approach that adopts advantages of both hypermedia and domain-application principles is to federate resources and include links to each. 1
GET /events/{id}
title: Lucan GP
id: {id}
href: /events/{id}
organised_by:
club:
title: Lucan Road Cycling Club
href: /clubs/lrcc
races:
- href: /events/{id}/races/{stage_id_a123}
- href: /events/{id}/races/{stage_id_a4W}
Originally posted by @rosscado in #57 (comment)
Develop a toolchain to build, test and deploy a Python application.
Define and run a basic integration test case(s).
Use Tavern as described in #7
As a means of evaluating the fitness and completeness of the API model, enter a real-world example into the development system.
The example we will use is the upcoming Laragh Classic.
https://cyclingireland.azolve.com/Workbench.mvc/public/eventDetails?EventId=1077384
All data must come from publicly available sources.
Publish an API that clients can query to retrieve a list of upcoming events.
GET /api/events
A JSON formatted array of events. For event format see #2.
{
"events": [
]
}
Connect a NOSQL database to the application.
Event
entities currently have a single field URL
representing the primary URL of the event.
Add more fields for other URLs promoting the event, if they exist e.g.
These could be represented as discrete fields if the number of supported URLs is low, or a nested list of fields if the number of URLs is high or unbounded.
Discrete
url_primary: http://www.sttiernanscc.com/
url_ci: https://cyclingireland.azolve.com/Workbench.mvc/public/eventDetails?EventId=1077384
Nested
urls:
primary: http://www.sttiernanscc.com/
cycling_ireland: https://cyclingireland.azolve.com/Workbench.mvc/public/eventDetails?EventId=1077384
List
urls:
- type: primary
url: http://www.sttiernanscc.com/
- type: Cycling Ireland
url: https://cyclingireland.azolve.com/Workbench.mvc/public/eventDetails?EventId=1077384
The raceready
CloudFoundy application in space production
fails to start.
The reason the application won't start is that there's no database service instance bound to the application.
That's because we only have a single Cloudant instance under the Lite plan and it's being used in staging already.
Find a way to share the single database instance (maybe different dbs within a single service instance?) or create a 2nd instance as appropriate.
Consider improving error handling so that the cause of the failure is more obvious from application logs. cf logs --recent
shows nothing informative.
Represent the racer categories A1, A2, etc. and which races are open to which categories.
Category Entity: /api/categories/
id: A+|A1|A2|A3|J|A4|W
description:
https://github.com/rosscado/raceready/wiki/Data-Model#category
Stages determine eligibility:
eligible_categories: [{CATEGORY}]
https://github.com/rosscado/raceready/wiki/Data-Model#stage
The stage entity's handicapped
field is not defined in the model.
It should be a boolean field with a default value of false
.
Originally posted by @rosscado in #57 (comment)
Separate the club entity from the POST event request, since we won't be recreating clubs on every event.
This will then require a means of looking up the club and linking the event to it.
E.g.
club:
id: Lucan Cycling Road Club
...
event:
organised_by:
club_id: Lucan Cycling Road Club
Or
club_id = GET /api/clubs/?title=Lucan Cycling Road Club
event:
organised_by:
club_id: {club_id}
Originally posted by @rosscado in #57 (comment)
Where's it on? Add location information to events.
Given:
Choose a web application framework:
Choose a set of REST API libraries over the framework.
Distinguish between different types of events, e.g. "road races" versus "time trials".
This will ultimately allow athletes to select/filter the types of races they prefer.
E.g. "show me all criteriums near me"
Create another worked example test case to shake out any further requirements and evaluate the enhancements delivered to support the Laragh Classic use case.
Cycling Ireland Event URL: https://cyclingireland.azolve.com/Workbench.mvc/public/eventDetails?EventId=1074983
Add a registration
field to Event
entities representing the ways in which racers can sign up for the event.
Example:
registration:
methods:
- type: online
url: https://register.primoevents.com/ps/event/FriendsFirstLaraghClassic2018
state: closed
- type: ontheday
state: limited
Save resources to a backend database.
Represent a stage's course
as laps (1 or more) of a circuit
(mapped route or segment).
races:
- title: Friends First Laragh Classic
eligible_categories:
- A1
- A2
stage_type: road race
handicapped: false
start_time: "2018-09-01 11:00"
course:
laps: 1
circuit_id: {circuit_id}
Add a field media
to event entities to hold promotional media like posters.
media:
poster:
Many of the better promoted events have poster images. These can be highly informative and will be important to display to athletes, but they will be impossible to parse programmatically.
The poster
field could be a URL to the online image, or an embedded image document itself. Saving the image within the application would be more resilient but would consume much more data.
Originally posted by @rosscado in #57 (comment)
Create a circuit entity at endpoint /api/circuits/
https://github.com/rosscado/raceready/wiki/Data-Model#circuit
Schema
id:
URL: web address of the mapped route or segment, e.g. Strava route/segment
elevation_gain_m: elevation gained (in metres) over one lap of the circuit, e.g. 250
distance_km: length (in kilometres) of one lap of the circuit, e.g. 12
flatness_index: computed, indicates how close to flat is the circuit, e.g. 0.15
Example
- name: Create the circuit
request:
url: "{api.server}/api/circuits/"
json:
url: https://www.mapmyride.com/routes/view/2189856949
distance_km: 86.95
elevation_gain_m: 1315
method: POST
headers:
content-type: application/json
response:
status_code: 201
For now all fields except flatness_index
will be populated by client POST/PUT requests exclusively. In later iterations distance_km
and elevation_gain_m
and other fields may be parsed from the route information at url
.
Define a simple test case and have it built as part of the toolchain.
The unit tests python -m pytest --ignore=tests/fvt
command is failing.
It was originally failing only on the delivery pipeline's BUILD
stage and passing locally, until I upgraded my local pip packages. Now it's failing locally too.
pip install -r requirements.txt
This will allow athletes to filter events to match their own category/categories.
The category in eligible_categories
list will match an id in /api/categories/{id}
. E.g. /api/categories/A1
.
Example:
stages:
- title: Friends First Laragh Classic
eligible_categories:
- A1
- A2
Allow for dates to be scheduled on a particular day.
I want the application to be implemented in Python3 but the toolchain init'ed from a node application.
Migrate from the Node.js buildpack to a Python buildpack.
In the Lucan GP use case (issue #57) the event details page states the distance of the races but not their route/course/circuits.
We must be able to capture the available race distance information when circuits are unavailable. Even if it turns out later to have a discrepancy with the circuit (e.g. if distance_km % circuit.distance_km != 0
) that's information we would want to represent too.
Requirement:
Add a distance_km
field to the Course
model.
Originally posted by @rosscado in #57 (comment)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.