Arrange pictures with links in a row streamlit - python

I have several icons that I want to line up at the end of the application. So that when I click on the image, I was transferred to a link. How should I do it?
So far, I have only managed to add this implementation through st.markdown.but they are arranged vertically because I added a new item every time I wrote markdown.

You can create custom components in streamlit using HTML. Maybe you can create a social media component.
Create a file my_component.html
<html>
<head>
<style>
.body {
height: 64px;
}
.parent {
width: 100%;
height: auto;
display: flex;
justify-content: center;
}
.child {
margin: 5px;
height: 32px;
width: 32px;
}
</style>
</head>
<body>
<div class="parent">
<a class = "child" href="https://www.google.com"><img src="https://upload.wikimedia.org/wikipedia/commons/thumb/5/53/Google_%22G%22_Logo.svg/1200px-Google_%22G%22_Logo.svg.png" alt="alt" style="width:32px;height:32px;"></a>
<a class = "child" href="https://wwww.reddit.com"><img src="https://www.redditinc.com/assets/images/site/reddit-logo.png" alt="alt" style="width:32px;height:32px;"></a>
<a class = "child" href="https://wwww.facebook.com"><img src="https://facebookbrand.com/wp-content/uploads/2019/04/f_logo_RGB-Hex-Blue_512.png?w=512&h=512" alt="alt" style="width:32px;height:32px;"></a>
</div>
</body>
</html>
I've added 3 links to google, reddit,and facebook respectively. Add or edit these to something custom.
In the streamlit file, you can import HTML files as components using the components library. The implementation I'm sharing is a very simplified version.
import streamlit as st
import streamlit.components.v1 as components
HtmlFile = open("my_component.html", 'r', encoding='utf-8')
source_code = HtmlFile.read()
print(source_code)
st.text("Navbar Component")
components.html(source_code)
It's a bit basic but yields something like this.

Related

css display: block is not working on flask?

I'm starting learning flask and I'm planning on makin a sorting algorithm visualizer using flask and I'm tryin to represent the elements of the array as bars (the height of the bars is = to the value of each element in the array). I'm thinking to use the display: block but it does not appear on the page. Pls help me or suggest anything if this is possible
html file:
<!DOCTYPE html>
<html>
<head>
<title>Sample</title>
<link rel="stylesheet" href="{{ url_for('static', filename='design.css') }}">
</head>
<body>
<div class="bar">
<p>test</p>
</div>
</body>
</html>
css file:
.bar{
display: inline-block;
height: 120px;
width: 5px;
background-color: red;
color: white;
}
this what only shows on my page. other css property works well this display: bar was the only problem
Normally this is an issue with browser caching. If you did not use a file and added it directly to <head> it should work
<head>
<style>
.bar{
display: inline-block; /*You want block or inline-block?*/
height: 120px;
width: 5px;
background-color: red;
color: white;
}
</style>
</head>
If you really want to use the css file, use versioning in the url:
/static/design.css/?v=1 next time /static/design.css/?v=2
But it becomes tedious. You can add a random variable like this:
import uuid
v = str(uuid.uuid4())
# url_for('static', filename='design.css', v=v)
Please clarify your answer using a screenshot of what is happening now

Trying to scrape image and I get empty output

I'm trying to scrape Twitter account image, I tried multiple ways and the output keeps give me empty list!
My Code:
import requests
from bs4 import BeautifulSoup
url = requests.get('https://twitter.com/jack/photo')
soup = BeautifulSoup(url.text, 'lxml')
image = soup.find_all('img')
print(image)
Output:
[]
That's a part of my project .. I tried lxml and find by class, but I still get nothing, maybe I'm missing something there but I don't know what it is.
If anyone can help me with it, I will be so appreciated.
Thanks in advance
I can see some React being used in the page. If you open the page and inspect the elements, you will see that as soon as you click on the photo to enlarge it, a new div appears as if from thin air. Which implies that that get created by react.
In order to address this you will need to use Selenium to open the page in a virtual browser, let the JavaScript do its magic and then look for the img tag.
You're trying to scrape the path for JavaScript twitter. If you examine the response of your page you will see the following snippit.
<form action="https://mobile.twitter.com/i/nojs_router?path=%2Fjack%2Fphoto" method="POST" style="background-color: #fff; position: fixed; top: 0; left: 0; right: 0; bottom: 0; z-index: 9999;">
<div style="font-size: 18px; font-family: Helvetica,sans-serif; line-height: 24px; margin: 10%; width: 80%;">
<p>We've detected that JavaScript is disabled in your browser. Would you like to proceed to legacy Twitter?</p>
<p style="margin: 20px 0;">
<button type="submit" style="background-color: #1da1f2; border-radius: 100px; border: none; box-shadow: none; color: #fff; cursor: pointer; font-size: 14px; font-weight: bold; line-height: 20px; padding: 6px 16px;">Yes</button>
</p>
</div>
</form>
I would recommend disabling javascript in your browser and then figuring out how to view the photos like that. Then you could mimic those requests using requests.
What worked for me was sendind a request to the path:
https://mobile.twitter.com/jack
Then using the css selector: class = "avatar". There should be one child, an image tag, grab the src of that image tag and that should be the link to your photo.
As requested, here is the python code I used:
import requests
from bs4 import BeautifulSoup
response = requests.get('https://mobile.twitter.com/jack')
soup = BeautifulSoup(response.text, 'lxml')
avatars = soup.findAll("td", {"class": "avatar"})
print(avatars[0].findAll('img')[0].get('src'))
Note: Twitter changes their layout frequently, so this may not work for long.

Custom template for HTMLTemplateFormatter with CSS styling for Bokeh DataTable

I am trying to set up a small Bokeh app with a DataTable that might contain long text depending on columns. I would like to have a nice tooltip tool to display the full truncated text while moving the mouse above the corresponding cell.
I went through a previous question that might perfectly do the job but I am unable to get the correct result.
Here is the previous question : How to add HoverTool to a Data Table (Bokeh, Python)
The solution I am investigating is the one provided by Ferrard with nice CSS styling.
Unfortunalety I know almost nothing about CSS and html.
Here are the code I am trying to reproduce.
main.py
main.py:
from os.path import dirname, join
import pandas as pd
from bokeh.io import curdoc, show
from bokeh.models import ColumnDataSource, Div
from bokeh.models.widgets import DataTable, TableColumn, HTMLTemplateFormatter
from bokeh.layouts import layout
template = """<div class="tooltip-parent"><div class="tooltipped"><%= value %></div><div class="tooltip-text"><%= value %></div></div>"""
df = pd.DataFrame([
['this is a longer text that needs a tooltip, because otherwise we do not see the whole text', 'this is a short text'],
['this is another loooooooooooooooong text that needs a tooltip', 'not much here'],
], columns=['a', 'b'])
columns = [TableColumn(field=c, title=c, width=20, formatter=HTMLTemplateFormatter(template=template)) for c in ['a', 'b']]
table = DataTable(source=ColumnDataSource(df), columns=columns)
l = layout([[table]])
curdoc().add_root(l)
show(l)
desc.html
<style>
.tooltip-parent {
width: 100%;
}
.tooltipped {
overflow: hidden;
width: 100%;
}
.tooltip-text {
visibility: hidden;
width: 250px;
background-color: rgba(0, 0, 0, 1);
color: #fff;
text-align: center;
border-radius: 6px;
padding: 5px 5px;
position: relative;
z-index: 1;
top: 100%;
left: 0%;
white-space: initial;
text-align: left;
}
.tooltipped:hover + .tooltip-text {
visibility: visible;
}
div.bk-slick-cell {
overflow: visible !important;
z-index: auto !important;
}
</style>
<h1>Tooltip demo</h1>
This is stupid but I really don't know where I should put the desc.html file in my working dir so the bokeh server can call it... I read through bokeh documentation and pay attention to Directory format for bokeh but did not manage to use either static or templates dir to achieve the proper result.
Here is the final result I am trying to have
https://i.stack.imgur.com/SB815.png (not enough reputation to link an image)
All I have on my side is the DataTable withouth the "Tooltip demo" header and without any tooltip working.
This is my first question on stack, hope everything is fine :)
In a directory style app, you can make a templates/index.html template that has this structure:
{% extends base %}
{% block title %}My Bokeh App{% endblock %}
{% block preamble %}
<style>
/* your styles here */
</style>
{% endblock %}
The app will automatically render itself using this index.html which has your stylesheet included. In general, it would be good for there to be easier ways to add extra stylesheet specifications to Bokeh apps. I'd encourage you to open a GitHub issue to start a discussion.

How do i place 2 CSS rectangles side by side? By default, they appear one below the other

Here is the code:
<head>
<meta http-equiv="refresh" content="01">
<title>
Slot Data
</title>
</head>
<body>
<style>
div
{
height: 100px;
width: 50px;
background-color: green;
}
</style>
<div></div>
<style>
div
{
height: 100px;
width: 50px;
background-color: green;
}
</style>
<div></div>
</body>
They appear exactly one below the other.
Also, I need a way to change the color "green" to "red" for a condition written in python. For which, the snippet is:
if count1 >= 0.65 * 122*85:
print "car0 absent"
cv2.rectangle(dst1,(8,8),(340,488),(0,255,0),2) #green
cv2.putText(dst1,'slot empty',(12,450), font, 1,(255,255,255),1,cv2.LINE_AA)
f = open('test.html','r')
filedata = f.read()
f.close()
newdata = filedata.replace("red","green")
f = open('test.html','w')
f.write(newdata)
f.close()
else:
print "car0 present"
cv2.rectangle(dst1,(8,8),(340,488),(0,0,255),2) #red
cv2.putText(dst1,'slot occupied',(12,450), font, 1,(255,255,255),1,cv2.LINE_AA)
f = open('test.html','r')
filedata = f.read()
f.close()
newdata = filedata.replace("green","red")
f = open('test.html','w')
f.write(newdata)
f.close()
and I have the same code for another car1.
How do i address the two rectangles differently? the replacing mechanism will replace the colors of both the CSS rectangles, which I do not want.
Any help is appreciated.
<div> are normally displayed as block level elements but can be made to display next to each other with display: inline-block.
You seem pretty new to CSS/HTML and might do well to do some research or tutorials to get a firmer grasp on things-- CSS can be strange at first, but gets much easier as you get more familiar with it.
Personally, I would use classes to target the elements appropriately. As for getting elements by class in Python, I'm not really sure-- I can't say I know off the top of my head how you are manipulating these things with Python at all-- is this displaying/executing in a browser?
I created a snippet below w/ an example.
.rect {
height: 100px;
width: 50px;
display: inline-block;
background-color: green;
}
.alert {
background-color: red;
}
<head>
<!--<meta http-equiv="refresh" content="01">-->
<title>
Slot Data
</title>
</head>
<body>
<div class="rect"></div>
<div class="rect alert"></div>
</body>
Please note, there are other ways to do this-- CSS provides all sorts of positioning/layout tools. Good luck!
You can use float:left to make them display next to eachother.
float:left
Just remember to clear it, if you want a second row. Just create a small element with the styling
clear:both;
Here's a handy fiddle that will really help in understanding how this css works:
https://jsfiddle.net/nfnneil/6jgsp9dx/

xhtml2pdf child elements show border of parent elements

Hoping someone may have solved this problem. Haven't seen anyone with it on Google.
I'm using xhtml2pdf in Python, trying to generate a simple document with a header, footer and my content is blocks of text with titles. I'd like to have a border around each piece of content but instead I get borders around each child element instead.
Here's my HTML
#page {
size: letter;
border: 0;
#frame header_frame {
-pdf-frame-content: header;
border: 0pt solid white;
left: .75in;
width: 7in;
top: .5in;
height: 1.5in;
}
#frame content_frame {
border: 0pt solid white;
left: .75in;
width: 7in;
top: 1.5in;
height: 7.5in;
}
#frame footer_frame {
-pdf-frame-content: footer;
border: 0pt solid white;
left: .75in;
width: 7in;
top: 9.5in;
height: 1in;
}
}
h1 {
padding-top: 5pt;
}
.desc {
margin-top: 3px;
margin-bottom: 3px;
padding: 3px;
border: 1px solid blue;
}
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<title>TEST TEST TEST</title>
</head>
<body>
<div id="header">
<h1>HEADER</h1>
</div>
<div id="footer">
FOOTER
</div>
<div class="desc">
<div class="title">TITLE OF ARTICLE</div>
<span>TEST 2</span>
<div>TEST 3</div>
<table>
<tr>
<td>Test4</td>
<td>Test 5</td>
</tr>
</table>
</div>
</body>
</html>
I'm just running the xhtml2pdf command line tool at the moment so there's no python to show. One thing I did notice when I run it in debug mode it shows "xhtml = false" even though I have an XHTML DTD. I'm not sure if this would make a difference.
Here's what I see in the browser and roughly what I expect the pdf to look like (ignoring the footer location of course):
Instead I get:
EDIT: I figured out that xhtml is an option to pass but passing it fails unless one has an old version of html5lib installed. Looks like the answer to my question is this library is not being actively maintained and I need to find a new solution :-/

Categories

Resources