Package: metaflow-card-html
HTML Metaflow CardRender raw HTML as aMetaflow card.Installationpipinstallmetaflow-card-htmlUsageTo use the HTML card, you need to supply thetype=htmlargument to the@carddecorator.  You can then set thehtmlattribute of your Flow to an html string you want to render:@card(type='html')@stepdeftrain(self):......self.html=some_html()# set some html to the self attributeIn these examples, we assumesome_htmlis returning a HTML string, like this:defsome_html():return"<html><body><h1 style='color: blue'>Hello World</h1></body></html>"However, you may want to use a different attribute name thanhtml.  To accomplish this, you can use theoptionsparameter of the@carddecorator.  For example, if we wanted to store our HTML in an attribute namedmyhtmlwe would do the following:@card(type='html',options={"attribute":"myhtml"})# set the attribute name to myhtml@stepdeftrain(self):......self.myhtml=some_html()# set the html like beforeError HandlingSome things to keep in mind about this card:This card is meant to render HTML passed as a string.  If you pass a non-string value, this card will attempt to render it as a string instead.Failure to render a card will not result in an error in the flow.Making Your Own Card ModulesYou may want to implement your own card modules to customize your own workflows.  This HTML card also serves as a great example of how to implement your own card modules.  You can follow the steps below to accomplish this:Step 1: Create a directory structureTo get started create the following directory structure:some_random_dir/ # the name of this dir doesn't matter
├ setup.py
├ metaflow_extensions/ # namespace package name 
│  └ card_html/ # NO __init__.py file, rename this folder to card_yourcardname
│      └ plugins/ # NO __init__.py file
│        └ cards/ # NO __init__.py file 
│           └ my_card_module/  # Name of card_module
│               └ __init__.py. # This is the __init__.py is required to recoginize `my_card_module` as a package
│               └ somerandomfile.py. # [Optional] some file as a part of the package. 
.If you are using GitHub, you can easily create this directory structure by usingthis template.  Otherwise, you can copy the directory structure inthe templateand modify it as indicated below.Note: Metaflow cards are distributed vianamespace packages, under the namespacemetaflow_extensions.  You need not worry about the mechanics of namespace packages to distribute or publish your own card module!  We recommend just following the directory structure indicated above.Step 2: Modify Files & Directory StructureAfter creating the necessary directory structure, you will need to modify the following files/directories:setup.py: review and change the parameters passed tosetupas appropriate.  Do not forget to add dependencies to other packages if they are required.Change the name of foldermetaflow_extensions/card_*tometaflow_extensions/card_<yourcardname>.  This is a suggestion to help keep the directory structure consistent with other cardsChange the name of the foldermetaflow_extensions/..../cards/htmltometaflow_extensions/.../cards/<yourcardname>Step 3: Create a Card ModuleIn__init__.pylocated inmetaflow_extensions/.../cards/<yourcardname>, you must import or define your custom card module. Here is a minimal example:frommetaflow.cardsimportMetaflowCardclassBasicCard(MetaflowCard):type="basic_card"defrender(self,task):# this function returns the HTML to be renderedreturntask.data.html# assumes you are saving an attribute named `html` in the taskCARDS=[BasicCard]Note that__init__.pyrequires aCARDSattribute which needs to be alistof objects inheritingMetaflowCardclass.What is shown above is only a minimal example.  Recall that in theHTMLcard, you can specify the name of the attribute via theoptionsparameter.  We can implement this functionality as follows:frommetaflow.cardsimportMetaflowCardclassHTMLCard(MetaflowCard):type='html'def__init__(self,options={"attribute":"html"},**kwargs):self._attr_nm=options.get("attribute","html")defrender(self,task):ifself._attr_nmintask:returnstr(task[self._attr_nm].data)# retrieves the html from the task by accessing `task[self._attr_nm]`CARDS=[HTMLCard]Step 4: Test Your CardNow that you have finished creating your custom card, you can install it so that it is  present in the python path.   You can then test your card by passing the correct argument fortypeto@cardas follows (no need to import anything):@card(type='helloworld')@stepdeftrain(self):......self.html=some_html()# set some html to the self attributeWe recommend setting up automated tests in CI if possible.  Take a look attests/and.github/workflows/for an example.  This is optional.Step 5: Publish Your CardYou are now ready to publish your card to pyipi.  If you have are not familiar with how to do this, you can follow the steps inthis tutorial.  For a more in-depth discussion on python packaging, you can readthis article.Step 6: Tell Everyone About Your Card :rocket:Now its time to let people know about your card!  You can make aPR to this READMEas well as letting us know on Twitter, tagging@MetaflowOSS.