Code Monkey home page Code Monkey logo

open5e-api's Introduction

Open5e logo

Open5e API

https://open5e.com
A JSON API for the D&D 5e ruleset


API homepage

API   •   Discord   •   Patreon

Table of contents

Table of contents generated with markdown-toc

Introduction

Open5e is a community project driven by a small number of volunteers in their spare time. We welcome any and all contributions! Please join our Discord to help out: https://discord.gg/9RNE2rY or check out the issue board if you'd like to see what's being worked on!

The API uses the Django REST Framework for it's browsability and ease of use when developing CRUD endpoints. It uses django's default SQLite database, and pulls the data from the /data directory.

Installation

Requirements

Dependencies

Pipenv is used to install all required packages from the Pipfile at the project root. Use the following command after cloning the project or switching branches.

pipenv install --dev

Development

Build

Crate a local database and import game content.

pipenv run python manage.py quicksetup --noindex

To make sure the API is always using your updated code, this command must be run again if:

  • You add/remove/edit Game Content
  • You edit Python code
  • You switch git branches

Search Indexing

To use the search function, you must build the search index by running the above command without the --noindex flag.

pipenv run python manage.py quicksetup

Run

Run the server locally. This server is only for development and shall not be used in production. The server will be available at http://localhost:8000.

pipenv run python manage.py runserver

If you need to run the server on another port, add the port number as an argument.

pipenv run python manage.py runserver $PORT

Building the OAS file

After completing a build, you can generate an OAS file to be used by another application.

pipenv run ./manage.py generateschema --generator_class api.schema_generator.Open5eSchemaGenerator > openapi-schema.yml` to build the OAS file.

Contributing

See contribution guide.

Tests

Tests are located in the api/tests directory. These should be run before pushing new changes to the main repository. These tests require that the api is running at http://localhost:8000.

pipenv run pytest

Approval tests

Approval tests are run against the approved files in api/tests/approved_files as *.approved.* . If a test fails then the recieved input will be stored in a *.recieved.* file. If you wish to approve the changes, replace the old approved file with the recieved file.

Recieved files shall not be included in the git repo.

Deployment

DigitalOcean

This deployment has been tested using DigitalOcean Apps with Docker Hub.

To start up the server from scratch on a droplet:

git pull https://github.com/open5e/open5e-api
export SECRET_KEY=a_new_secret_key
export SERVER_NAME=whatever.yourdomain.com
cd open5e-api/
docker-compose up

Railway.app

  1. Create a fork on Github. This is used to automatically deploy whenever you make a change.
  2. Login with your Github account on Railway.app and give it access to manage your forked repository.
  3. Create a new Project and choose 'Deploy from GitHub repo'. Select your fork in the list.
  4. Keep all settings default and deploy. Accept when Railway asks to copy variables existing variables from the repository.
  5. Add the variable PORT with the value 8888.
  6. Add the variable SERVER_NAME with the Railway-provided domain or add your own.
  7. Push a commit to Github and watch your open5e-api redeploy in minutes!

Docker

With docker installed, you can build the project with provided Dockerfile

docker build

This docker app can then be deployed with any provider.

open5e-api's People

Contributors

augustjohnson avatar bradyslot avatar calumbell avatar coderatul avatar colbyrush avatar daft-develop avatar dashron avatar daydin avatar dependabot[bot] avatar dprothero avatar eepmoody avatar gbalbuena avatar gredelston avatar gredelston-at-google avatar guizesilva avatar jakdevmail avatar jonathanelawrence avatar mccrossin avatar michaeleconomy avatar mshea avatar nstefanski avatar paullofte avatar realdeuce avatar roberthead avatar sturlen avatar tetra-cube avatar thelukester92 avatar txtsd avatar w8bsd avatar wardsky avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

open5e-api's Issues

Add spells from Level Up Advanced 5e

Level up advanced 5e has many spells that both modify existing 5e SRD spells and includes entirely new ones. These are all out under the OGL.

You can find the spells here:

https://a5e.tools/spells

They can likely be scraped or if that proves troublesome, I can reach out to EN World Publishing to see if we can get the database.

Desert Giant

Just letting people know that there's a glitch on the Desert Giant entry. There are others and I'm happy to point them out when I find them.
2021-03-11 13_50_10-Open5e - Desert Giant

As you can see, Perception is showing as $1. Probably should fix that.

Consider splitting the /data/ into it's own repository.

I really like the concept of separation of concerns, so that the API is pure python, but at build time it pulls data (which is nicely json formatted) into itself. Then the data can be freely updated without python being touched, and a nice landing page can be made that includes the data.
I would suggest even making jekyll pages and possibly even a smaller, static-api style json page. It could not include search, but it could include plenty of other stuff.
https://jekyllrb.com/docs/datafiles/
Basically:
open5e-data would primarily be a json data repo, and would have a couple of front-matter type pages in jekyll that would allow for simple browsing of the site. It could have a nice readme, and all content could be properly licensed as CC.

Impacts:
New repo, including some new documentation.
New API build process, where the API would pull from a live repo. Maybe the open5e-data repo has build artifacts?
Some updates to the frontend to create those references.

Support passing multiple values for filtering

To support a more advanced search API it would be great to be able to provide a list of attributes to filter on.

the example here would be asking for all monsters CR 1 & 2

/monsters/?challenge_rating=1&challenge_rating=2

another option would be searching for multiple types of monsters, or any other attribute that is a string

"Player's handbook" spells not in the Systems Reference Document

I realize the recent license adventure might make this a tricky question, but in general: There's a set of spells which are only present in the 5e "Player's handbook", and not in the "Systems Reference Document". For example, the Blade Ward cantrip.

Would it be ok to add a json with the extra spells of the Player's Handbook (and perhaps other items) to this project? Most other wiki/collection sites do seem to have all those spells added in some shape or form.

Items returned

I've looked around the documents a bunch but can't find this, is there a way to limit the number of results returned? Default is 50 and I wanted to lower this.

Thanks!

Strange techie-looking "Sage Advice :class: official" headers

"Sage Advice" clarifications to rules seem to be shown with a header that looks like it needs formatting: see for example Uncanny Dodge https://beta.open5e.com/classes/rogue which shows:

image

which looks like it should have been altered to be a pretty header and a formatted blockquote in some way, but hasn't been. The Sage Advice clarifications don't seem to be in this repository, so I can't look at patching it, but perhaps this is something that's currently already being worked on?

Set up API versioning

Alice uses the Open5E API to power her webapp, a virtual tabletop (VTT). Her webapp queries the API when it needs monster stats. It's stable and it works.

Bob is a developer for the Open5E API. He figured out a new way to organize the Monster table. He realized that the challenge_rating field would be better as a float rather than a string, so he created a new cr field. He wants to delete the old challenge_rating field. (Based on a true story: see #84)

Bob has two choices:

  1. Delete the challenge_rating field. This will break Alice's VTT until she fixes it.
  2. Leave the legacy challenge_rating field in there forever to prevent breaking Alice's VTT.

Neither of these options is great. Currently we prefer option 2 because we don't want to break our consumers. If we always do this, our code base will just accumulate tech debt forever. It will become increasingly confusing for both O5E developers and consumers.

There is another solution, which is for us to set up API versioning. In this case, events could transpire like this:

  1. Open5E releases Version 1.0.0.
  2. Alice pins her webapp to point to O5E Version 1.0.0.
  3. Bob implements cr and merges it to O5E Version 1.0.1. He marks challenge_rating for deprecation.
  4. Because Alice's O5E integration is stable, she doesn't pay attention to the new O5E release. She stays pinned to 1.0.0, using the now-deprecated challenge_rating field.
  5. Some time later, the O5E API gets ready to release Version 2.0.0. Bob deletes the deprecated challenge_rating field. This is a breaking change, but that's OK because this is a "major release". Alice is unaffected by this deletion, since she's still pinned to 1.0.0.
  6. Some time later, Alice decides she wants access to some cool new O5E API features. She wants to upgrade to O5E Version 2.0.0. At first, she naively tries to just change the API version number in her app config, but she gets test failures for the deleted challenge_rating field. She checks the release notes and sees that this field was deleted. Alice starts using the cr field, then updates her app config. Her VTT experiences no downtime.

Obviously, there's a lot to think through for implementing this feature. Hopefully this story makes it a little easier to understand the need.

Some questions that come to mind...

  1. What versioning scheme do we want to use?
  2. What kinds of features are OK to put into a major release vs. a minor release vs. etc?
  3. Are we going to hit storage problems with hosting different versions of our entire database?
  4. Can consumers still subscribe to the nightly build or to tip-of-tree if they want bleeding-edge features?
  5. Who is going to write release notes? How will we manage the information that needs to go into that?
  6. What API version should our website point to? Do we need to set up a website versioning scheme, too?

Adjust/regenerate Spells to include Classes as an array

Currently this is only available as a string "wizard, druid, cleric". It'd be great if it was an array of strings instead. ["wizard", "druid", "cleric"] so that it can be better used for filtering, and parsed in cleverer ways on the frontend.

Check if API Updated

Hello!

Is there a way to tell weather or not the API has been updated? I do not see any sort of version string within the hierarchy of the API data. I apologize if there is already and obvious answer to this question, and I am just missing it.

For more context, I am writing a desktop app (incomingstick/OpenRPG-App) and store the API data locally. I would like to have a way to check whether or not the local data needs to be updated from the API, ideally without needing to pull the entire tree, and without needing to check against GitHub or a git repository. For now I am just running a function to pull the entire data tree from your API on the app start, but that is less than ideal.

I am willing to implement this if you have thoughts on what type of data versioning you would like to see used.

Write API (Post/Put)

Hi,

I have started to use open5e-api to standardise my personal content, to have a centralised awsesome search for all my 5e content.

With that, I would like to confirm if open5e-api provides any write API so I can Post/Put my OCRed content to the application on my local server?

If not the only way to inject data to the platform is using the .json files using the same pattern?

`populatedb --flush` is buggy: does not actually flush all data sources, and can flush after populating

When you run manage.py populatedb --flush data/my_data_source/, it doesn't actually flush all data sources. It only flushes the data sources that exist in the given directory. So if my_data_source doesn't contain a monsters.json file, then the Monsters db will not be flushed.
It turns out that this matters. Our current quickload and quicksetup scripts call manage.py populatedb --flush ./data/open5e_original, and then call all the others with --append. But open5e_original only has three datafiles: backgrounds, documents, and spells. So indeed, despite our best intentions, we never flush classes, races, monsters, conditions, etc.

Second problem. manage.py populatedb allows us to pass in multiple data sources, if you want. What happens if you run manage.py populatedb --flush dir1/ dir2/? The behavior you would expect to see is that we flush everything, and then import all the JSON from dir1, and then import all the JSON from dir2.
But nope! What actually happens is, for each data source in dir1, we flush and then import; and then for each data source in dir2, we flush and then import. The problem is, we'll wind up flushing everything we imported from dir1! To paraphrase a propane salesman, that behavior ain't right.
This one doesn't actually matter for our quickload and quicksetup scripts, since we're never actually passing in more than one directory (for some reason), but it's still a bug.

We should refine the behavior of populatedb --flush. The correct behavior would be, if --flush is passed in, flush ALL models regardless of what JSON files are present, and then start populating each passed-in directory.

Implement a "random" api request

For example:

If I make a request to monsters but include a argument that's something like random=1, then it returns 1 randomized monster that also meets the filter criteria.

Adventuring Gear subsection of Equipment is cut off partway through & missing content

On this page: https://open5e.com/sections/adventuring-gear

The content cuts off midway through the entry for a Holy Symbol. From the SRD, I'd guess that the quotation mark may be causing an issue with a string, or similar. I've bolded where the cut-off starts & italicized the entry's missing content:

Holy Symbol. A holy symbol is a representation of a god or pantheon. It might be an amulet depicting a symbol representing a deity, the same symbol carefully engraved or inlaid as an emblem on a shield, or a tiny box holding a fragment of a sacred relic. Appendix PH-B "Fantasy-Historical Pantheons" lists the symbols commonly associated with many gods in the multiverse. A cleric or paladin can use a holy symbol as a spellcasting focus. To use the symbol in this way, the caster must hold it in hand, wear it visibly, or bear it on a shield.

All the Adventuring Gear content after "Appendix PH-B" is missing, including other gear descriptions and the table of prices etc for mundane gear.

Monsters missing descriptions

So in this file: https://github.com/eepMoody/open5e-api/blob/master/data/WOTC_5e_SRD_v5.1/monsters.json

I'd expect it to contain the descriptions for monsters from here:
https://media.wizards.com/2016/downloads/DND/SRD-OGL_V5.1.pdf
(not all monsters have descriptions, but a lot of them do).

In case me or someone else gets motivated to fix this:
Did you generate the JSON file by hand? or by parsing the pdf?

What should the name of the description property be? ("description" is nice and clear, but "desc" is more consistent with the rest of the file).

Rewrite quickload.py and quicksetup.py as shell scripts.

in api/management/commands/ there are two files that are basically just shell scripts. They should be actually re-written as shell scripts. It's probably safe to assume development will be occurring on something with bash at this point. These files were originally written to assist windows developers.

Using python to launch python for this purpose is a bit of a round peg square hole type thing, and should be avoided.

README.md would have to be adjusted.
Dockerfile could potentially be adjusted to take advantage of quickload, although this is not required at the moment.

Introduce API versioning system

Currently, the API cannot be versioned. Any substantial changes to existing data or responses would be a regression affecting consumers of the API.

Ideally, we would want to introduce something that provides versioned API responses using a format like /v2/monsters/ so we can make breaking changes when needed.

The number of versions should stay small and such changes should be rare, so this doesn't need to be easy to set up.

A decision would need to be made about what the versionless API endpoint would be: should it stay as v1, or should it transition to being the evergreen "current" version? If the latter, how do we notify consumers in advance of the change?

API should expose page numbers

We have received a request to populate monsters' page numbers, where possible, and expose them on the API. In particular, we have received page# data for data/menagerie/monsters.json from Mike Shea. In order to support this FR, we'll need to:

  1. Create a new page# field. I propose that we do this on the GameContent abstract model, which will make it available on the Monster table as well as on other tables such as Spell, CharClass, etc. I propose that we call the field page_no. When a data source has a physical version, page_no should reference the physical page number, even if the PDF version has extra pages at the beginning (ex. cover page). If the PDF version is the canonical source, then that's moot.
  2. Populate the field in data/menagerie/monsters.json via the data Mike provided.
  3. Expose the new field on the Monsters API view.

Bump Python version to 3.11

Currently this project runs on python3.8, which is a legacy security release. The latest stable release is 3.11. If we upgrade to 3.11, we get access to all kinds of cool features, including:

  • Better type hints
  • Structural pattern matching (i.e., the match statement)
  • Exception groups
  • .toml parsing (useful for, say, if we want to start using pyproject.toml)
  • Bunch of random new functions, like str.removeprefix
  • Speed gains averaging 22%
  • Devs won't have to install a legacy version of Python

Set up automated unit tests

I'm not even asking for full test coverage here. Here are my desiderata:

  1. At least one unit test. That should be easy to write, right? Django makes automated tests easy to write and to run.
  2. Ensure that tests run during the CI check. (TBH this would be good for me to implement since I want to learn how our CI works.)
  3. Bonus feature: Run tests as a preupload hook? I'm wary of making the upload too long, and it might be redundant with running during CI... but it also might be convenient for devs who don't want to get suddenly confused when their beautiful PR fails checks. But also, that's what CI checks are for. I'm conflicted about this part!

My main goal with this ticket is to get us started so that we can easily add more tests in the future.

Add environment tags to monsters

Jump in to the discord thread to discuss more: thread

Might also eventually want filtering by this on the UI, might make be good to make a project to sync across front/back end

Add additional action attributes like reach, damage type and number of targets

Currently actions only have the following data in json: attack_bonus, damage_bonus, damage_dice, name and desc.

It would be nice to have reach, damage type, and number of targets too so they can be used programmatically. Also, uses per day.

Later on, perhaps, we could have more attributes for DC_on_hit and status_on_fail for any statuses applied like diseased.

Progress:

  • reach
  • range_normal
  • range_max
  • damage_type
  • on_hit
  • on_crit
  • multiattacks
  • complex attacks
  • attack bonus with specific weapon

Bulk create/update models during populatedb

Right now, quickload and quicksetup take a long time to run. It would be nice to make them faster, especially since we'll probably add more content sources in the future.

The primary reason for the slowness is saving models to the DB. Currently, importer.py saves each model one-at-a-time. Django provides bulk_create() and bulk_update() methods for saving a whole bunch of models at once. We should start using those. I think it could cut our populatedb time by 50% or more.

Can't search for spell solely by name

Not sure if this intended or not. Since the search fields on the spell viewset are:
search_fields = ['dnd_class', 'name']
When I went to search for the spell "druidcraft" by
/?search=druid
It will return all druid spells.
I think ideally search for spells would only search by name since we can already filter by dnd_class
as in the spell filters
'dnd_class': ['iexact', 'exact', 'in', 'icontains'],

So I would propose removing 'dnd_class' from the search fields.

Let me know if I'm misunderstanding something

API endpoints for Combat and Gameplay Mechanics

From what I can tell there is currently not an API endpoint to get information from the following sections that the front end has:

Combat:

  • Actions in Combat
  • Attacking
  • Combat Sequence
  • Cover
  • Damage & Healing
  • Mounted combat
  • Movement in Combat
  • Underwater Combat

Gameplay Mechanics:

  • Ability Scores
  • Between Adventures
  • Environment
  • Movement
  • Objects
  • Rest
  • Saving Throws
  • Time

I imagine this may be as easy as adding each of these sections to data/WOTC_5e_SRD_v5.1/sections.json

This doesn't sound too hard as it looks like just converting the html you have in the UI to markdown and then adding to the json file. I think I can make a PR but I wanted to ask before I put work into it.

Data origins

Greetings!

Just curious where the original data comes from, for legal/copyright reasons. There are several others resources that are also based on 5e SRD (such as 5e-database) . What I cant figure out is if there is a root canonical data source that clearly does not include any copyrighted content (IE, no accidental inclusion of something WOTC specific).

If you have any insight into this would def appreciate it!

api.open5e.com dataset out of sync with master branch

Hello @eepMoody!

Really enjoy Open5e-api, thank you for all the work on setting it up.

I was going through some of the pull requests for fixes to the WotC SRD monsters.json and I've noticed a few commits to WoTC 5.1/monster.json don't appear on the live api.

One example:

on master, updated Giant Wasp correctly removes "swim speed" per #68
https://github.com/eepMoody/open5e-api/blob/efcf490bed1152746b5a214847a2c7401db22fcf/data/WOTC_5e_SRD_v5.1/monsters.json#L8848

However, on the API, the original (incorrect) data is still present:
https://api.open5e.com/monsters/?challenge_rating=&armor_class=&type=&name=Giant+Wasp&document=&document__slug=

I suspect the Django database may just be out of date and needs a flush to rebuild against the WoTC .json's. I wasn't sure if this was something you simply did periodically, or it got missed.

Add AND/OR operators for searching resources

Eg.

So that you can find spells that are in common with two classes like "wizard+bard", in either of two classes like "wizard,bard" and in one class but not the other "-wizard,bard"

Queryable mechanics, such as Abilities and Proficiencies

See discussion thread on Discord: https://discord.com/channels/470638316103008268/1086682420704727110

Original request comes from @Sturlen on Discord:

Having a more structured way of getting rules data such as Ability Scores would be helpful building Character Sheets or VTTs. It would also make it easier to create links to specific rules for the Open5e website e.g open5e.com/gameplay-mechanics/ability-scores#advantage-disadvantage

Sturlen's primary usage example is mechanics for hover-tips on ability scores, such as (for Strength): Measuring physical power. We also thought it could be useful to do this for Proficiencies and Skills.

I propose that we add a new table Mechanic, like so:

class Mechanic(models.Model):
    name: str
    slug: str
    category: str # Either "ABILITY", "PROFICIENCY", or "SKILL" (for now)
    brief_description: str
    parent_section: Section # To reference the longer rules

We can also expose separate API endpoints for Ability, Proficiency, and Skill, each of which queries this table with a filter on .category.

Thoughts:

  1. Does it make the most sense to have Mechanic as one generic table, or should we instead have separate tables for Ability, Proficiency, Skill?
  2. Should we have a separate MechanicCategory table to future-proof against changing category strings?
  3. Is Mechanic an OK name? Are skills not also mechanics? Maybe BasicMechanic, BasicRule, something else...?
  4. Do we need to update any other tables to reference these? For example, perhaps CharClass should reference the skills for the proficiency list.

Add docstrings to files, classes, functions

More and more devs are joining the project, thanks to the shout-out on SlyFlourish's podcast. As projects scale and gain contributors, style and documentation become increasingly important. Let's start by adding docstrings.That way, new contributors will know what they're doing, and they will be encouraged to document their own code, too.

I propose that we follow PEP 8 for overall Python style and PEP 257 for docstring conventions specifically.

Missing armour

It appears that armour is nowhere available within the API

Add Kobold Press Player Races

Kobold Press has some player races that fall under their OGL, maybe other publishers do the same thing? Since we have stuff from "Tome of Beasts" why not include other stuff besides Monsters that fall under OGL, like "Classes", "Subclasses", "Spells", and "Races"?

Source: http://kpogl.wikidot.com/

Sub-races as fk resources on races

Subraces aren't listed: is the plan to have them as their own endpoint or as a child of each race?

Intent is to include sub-races as linked resources for races (and vice-versa).

Less than or equals in filter

Hey there, thank-you for this project first off.

I'm just toying with the idea of setting up a Bestiary of sorts for a druid in my game - their Wild Shape runs off of beasts below a certain CR.

In this I'm wondering if it's possible to filter using less then or greater then?

Thanks again!

Enable custom hosting with custom entities

Paraphrasing a user story I heard from @augustjohnson:

As a DM and a techy, I want to clone my own instance of open5e for my players, and add my own entities (items, monsters, ...) to it.

That's the vision more or less, but it implies that data and server are disconnected, and UI / API are self-hostable, and that there's a decently easy on-ramp for data creation.

What features are currently missing for this to be possible? I think we need some separation of "upstream" vs. "custom" entities. Beyond that, needs further investigation.

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.